Forum Rule: Always post complete source code & details to reproduce any issue!
Page 7 of 11 FirstFirst ... 5 6 7 8 9 ... LastLast
Results 151 to 175 of 265

Thread: RA8876LiteTeensy For Teensy T36 and T40

  1. #151
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    6,959
    So far my quick 5 minute look hopefully makes it easier to find things. So I would suggest going for it!

    At some point will be interesting to see how much we can speed things up. Looks like everything is going through SPI.transfer or SPI.transfer16. It does look like it supports the
    DMA version of the SPI Transfer, but we don't have any support for 16 writes that way...

    So will be interesting to see how well the SPI buss is kept busy. Looks like gaos after each group. Not too bad... But also it is running at 5mhz... Runs at 30... Did not at 50...

    But at 30 you can see some pretty good gaps between outputs...

    Click image for larger version. 

Name:	screenshot.jpg 
Views:	17 
Size:	47.9 KB 
ID:	20384

    Now to go relax for the rest of the night.

  2. #152
    Senior Member+ defragster's Avatar
    Join Date
    Feb 2015
    Posts
    11,837
    Great to see it working - and room for some transfer improvement.

  3. #153
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    5,373
    @KurtE
    Pushed the changes but GitHub was acting funny for the merges so it there is a problem may have repush the changes.

    Anyway fixed one problem with setactiveWindow so now the backfills and screen fills are correct for anti-alias font. Not sure yet why the characters are not printing - that's next I guess.

    EDIT: Just pushed the fix so anti-alias fonts will display. CENTERING is whats left
    Last edited by mjs513; 05-31-2020 at 11:59 AM.

  4. #154
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    6,959
    Morning:

    If you wish to try out the font test 4... I have a version up in a soon to be deleted branch Will migrate into the main WIP branch:
    Code:
    #include <Adafruit_GFX.h>
    
    #include <SPI.h>
    #include "RA8876_t3.h"
    #define RA8876_CS 10
    #define RA8876_RESET 9
    #define BACKLITE 7 //External backlight control connected to this Arduino pin
    
    #include "font_Arial.h"
    #include "font_ArialBold.h"
    #include "font_ComicSansMS.h"
    #include "font_OpenSans.h"
    #include "font_DroidSans.h"
    #include "font_Michroma.h"
    #include "font_Crystal.h"
    #include "font_ChanceryItalic.h"
    
    // maybe a few GFX FOnts?
    #include <Fonts/FreeMonoBoldOblique12pt7b.h>
    #include <Fonts/FreeSerif12pt7b.h>
    
    typedef struct {
      const ILI9341_t3_font_t *ili_font;
      const GFXfont       *gfx_font;
      const char          *font_name;
      uint16_t            font_fg_color;
      uint16_t            font_bg_color;
    } ili_fonts_test_t;
    
    const uint16_t  PINK       = 0xFCFF; // M.Sandercock
    const uint16_t  PURPLE       = 0x8017; // M.Sandercock
    
    const ili_fonts_test_t font_test_list[] = {
      {nullptr, nullptr,  "Internal Font", RED, YELLOW},
      {&Arial_14, nullptr,  "Arial_14", WHITE, WHITE},
      {&Arial_14_Bold, nullptr,  "ArialBold 14", YELLOW, YELLOW},
      {&ComicSansMS_14, nullptr,  "ComicSansMS 14", GREEN, GREEN},
      {&DroidSans_14, nullptr,  "DroidSans_14", WHITE, WHITE},
      {&Michroma_14, nullptr,  "Michroma_14", YELLOW, YELLOW},
      {&Crystal_24_Italic, nullptr,  "CRYSTAL_24", BLACK, YELLOW},
      {&Chancery_24_Italic, nullptr,  "Chancery_24_Italic", GREEN, GREEN},
      {&OpenSans24, nullptr,  "OpenSans 18", RED, YELLOW},
      {nullptr, &FreeMonoBoldOblique12pt7b,  "GFX FreeMonoBoldOblique12pt7b", WHITE, WHITE},
      {nullptr, &FreeMonoBoldOblique12pt7b,  "GFX FreeMonoBoldOblique12pt7b", RED, YELLOW},
      {nullptr, &FreeSerif12pt7b,  "GFX FreeSerif12pt7b", WHITE, WHITE},
      {nullptr, &FreeSerif12pt7b,  "GFX FreeSerif12pt7b", RED, YELLOW},
    
    } ;
    
    extern void displayStuff(const char *font_name);
    
    
    RA8876_t3 tft = RA8876_t3(RA8876_CS, RA8876_RESET); //Using standard SPI pins
    
    uint8_t test_screen_rotation = 0;
    
    
    void setup() {
      Serial.begin(38400);
      long unsigned debug_start = millis ();
      while (!Serial && ((millis () - debug_start) <= 5000)) ;
      Serial.println("Setup");
      tft.begin();
      pinMode(BACKLITE, OUTPUT);
      digitalWrite(BACKLITE, HIGH);
    
    
    //  tft.setRotation(4);
      tft.fillScreen(BLACK);
      tft.setTextColor(WHITE);
      tft.setFont(Arial_14);
      displayStuff("Arial_14");
    
      tft.setTextColor(YELLOW);
      tft.setFont(Arial_14_Bold);
      displayStuff("ArialBold 14");
    
      tft.setTextColor(GREEN);
      tft.setFont(ComicSansMS_14);
      displayStuff("ComicSansMS 14");
    
      nextPage();
      tft.setTextColor(WHITE);
      tft.setFont(DroidSans_14);
      displayStuff("DroidSans_14");
    
      tft.setTextColor(YELLOW);
      tft.setFont(Michroma_14);
      displayStuff("Michroma_14");
      stepThrough();
    
      tft.setTextColor(BLACK, YELLOW);
      tft.setFont(Crystal_24_Italic);
      displayStuff("CRYSTAL_24");
    
      nextPage();
    
      tft.setTextColor(GREEN);
      tft.setFont(Chancery_24_Italic);
      displayStuff("Chancery_24_Italic");
    
      //anti-alias font OpenSans
      tft.setTextColor(RED, YELLOW);
      tft.setFont(OpenSans24);
      displayStuff("OpenSans24");
    
      Serial.println("Basic Font Display Complete");
      Serial.println("Loop test for alt colors + font");
    }
    
    void loop()
    {
      Serial.printf("\nRotation: %d\n", test_screen_rotation);
      //tft.setRotation(test_screen_rotation);
      tft.fillScreen(RED);
      tft.setCursor(tft.width()/2, tft.height()/2/*, true*/);
      tft.printf("Rotation: %d", test_screen_rotation);
      test_screen_rotation = (test_screen_rotation + 1) & 0x3;
      tft.setCursor(200, 300);
      Serial.printf("  Set cursor(200, 300), retrieved(%d %d)",
                    tft.getCursorX(), tft.getCursorY());
      tft.setCursor(50, 50);
      tft.write('0');
      tft.setCursor(tft.width() - 50, 50);
      tft.write('1');
      tft.setCursor(50, tft.height() - 50);
      tft.write('2');
      tft.setCursor(tft.width() - 50, tft.height() - 50);
      tft.write('3');
    
      for (uint8_t font_index = 0; font_index < (sizeof(font_test_list) / sizeof(font_test_list[0])); font_index++) {
        nextPage();
        if (font_test_list[font_index].font_fg_color != font_test_list[font_index].font_bg_color)
          tft.setTextColor(font_test_list[font_index].font_fg_color, font_test_list[font_index].font_bg_color);
        else
          tft.setTextColor(font_test_list[font_index].font_fg_color);
        if (font_test_list[font_index].ili_font) tft.setFont(*font_test_list[font_index].ili_font);
        else if (font_test_list[font_index].gfx_font)  tft.setFont(font_test_list[font_index].gfx_font);
        else tft.setFontDef();
        tft.println(font_test_list[font_index].font_name);
        displayStuff1();
      }
      nextPage();
    }
    
    void displayStuff(const char *font_name)
    {
      elapsedMillis elapsed_time = 0;
      tft.println(font_name);
      tft.println("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
    //  stepThrough();
      tft.println("abcdefghijklmnopqrstuvwxyz");
    //  stepThrough();
      tft.println("0123456789");
    //  stepThrough();
      tft.println("!@#$%^ &*()-");
    //  stepThrough();
      tft.println(); tft.println();
    //  stepThrough();
      Serial.printf("%s: %dms\n", font_name, (uint32_t)elapsed_time);
    }
    
    uint32_t displayStuff1()
    {
      elapsedMillis elapsed_time = 0;
      tft.println("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
      tft.println("abcdefghijklmnopqrstuvwxyz");
      tft.println("0123456789");
      tft.println("!@#$%^ &*()-");
    
      int16_t cursorX = tft.getCursorX();
      int16_t cursorY = tft.getCursorY();
    
      uint16_t width = tft.width();
      uint16_t height = tft.height();
      Serial.printf("DS1 (%d,%d) %d %d\n", cursorX, cursorY, width, height);
      uint16_t rect_x = width / 2 - 50;
      uint16_t rect_y = height - 75;
      tft.drawRect(rect_x, rect_y, 100, 50, WHITE);
      for (uint16_t y = rect_y + 5; y < rect_y + 50; y += 5)
        tft.drawFastHLine(rect_x + 1, y, 98, PINK);
      for (uint16_t x = rect_x + 5; x < rect_x + 100; x += 5)
        tft.drawFastVLine(x, rect_y+1, 48, PINK);
      tft.setCursor(width / 2, height - 50/*, true*/);
      tft.print("Center");
    
      // Lets try again with CENTER X keyword.
      rect_y -= 100;
      tft.drawRect(rect_x, rect_y, 100, 50, PINK);
      for (uint16_t y = rect_y + 5; y < rect_y + 50; y += 5)
        tft.drawFastHLine(rect_x + 1, y, 98, CYAN);
      for (uint16_t x = rect_x + 5; x < rect_x + 100; x += 5)
        tft.drawFastVLine(x, rect_y+1, 48, CYAN);
    //  tft.setCursor(CENTER, rect_y);
      tft.print("XCENTR");
    
      // Lets try again with CENTER Y keyword.
      rect_x = 50;
      rect_y = tft.height()/2 -25;
      tft.drawRect(rect_x, rect_y, 100, 50, CYAN);
      for (uint16_t y = rect_y + 5; y < rect_y + 50; y += 5)
        tft.drawFastHLine(rect_x + 1, y, 98, PINK);
      for (uint16_t x = rect_x + 5; x < rect_x + 100; x += 5)
    //  tft.setCursor(50, CENTER);
      tft.print("YCENTR");
      
      // Lets see how close the getTextBounds gets the bounds of the text
      rect_x = 200;
      rect_y += 25; //center 
      static const char rectText[] = "RectText";
      int16_t xT, yT;
      uint16_t wT, hT;
      tft.getTextBounds(rectText, rect_x, rect_y, &xT, &yT, &wT, &hT);
      Serial.printf("getTextBounds: (%d, %d): %d %d %d %d\n", rect_x, rect_y, xT, yT, wT, hT);
      tft.setCursor(rect_x, rect_y);
      tft.print(rectText);
      tft.drawRect(xT, yT, wT, hT, CYAN);
    
      tft.setCursor(cursorX, cursorY);
      static const char alternating_text[] = "AbCdEfGhIjKlMnOpQrStUvWxYz\raBcDeFgHiJkLmNoPqRsTuVwXyZ";
    
      for (uint8_t i = 0; i < sizeof(alternating_text); i++) {
        if (i & 1) tft.setTextColor(WHITE, RED);
        else tft.setTextColor(YELLOW, BLUE);
        tft.write(alternating_text[i]);
      }
    
      tft.println(); tft.println();
    
    
    
      return (uint32_t) elapsed_time;
    }
    
    void nextPage()
    {
      Serial.println("Press anykey to continue");
      while (Serial.read() == -1) ;
      while (Serial.read() != -1) ;
    
      tft.fillScreen(BLACK);
      tft.setCursor(0, 0);
    }
    void stepThrough()
    {
      Serial.println("Press anykey to continue");
      while (Serial.read() == -1) ;
      while (Serial.read() != -1) ;
    }
    Not sure which route to take next... Continue here to figure out some of the things missing.

    See about maybe adding some of the things like PWM backlight So don't need IO pin, Or SPI speedup...
    Or back to Robot


    : I updated the above sketch to Serial.printf the name of font and how long the display of it took in the initial displayStuff, as a way to then see how much it can be sped up.

    Example run:
    Code:
    Setup
    
    Arial_14: 89ms
    ArialBold 14: 89ms
    ComicSansMS 14: 109ms
    Press anykey to continue
    
    DroidSans_14: 95ms
    Michroma_14: 112ms
    Press anykey to continue
    
    CRYSTAL_24: 451ms
    Press anykey to continue
    
    Chancery_24_Italic: 228ms
    OpenSans24: 1473ms
    Basic Font Display Complete
    
    Loop test for alt colors + font
    EDIT2 - changed from 5mhz to 30...
    Code:
    Setup
    
    Arial_14: 22ms
    ArialBold 14: 22ms
    ComicSansMS 14: 27ms
    Press anykey to continue
    
    DroidSans_14: 23ms
    Michroma_14: 28ms
    Press anykey to continue
    
    CRYSTAL_24: 110ms
    Press anykey to continue
    
    Chancery_24_Italic: 56ms
    OpenSans24: 368ms
    Basic Font Display Complete
    
    Loop test for alt colors + font
    Last edited by KurtE; 05-31-2020 at 01:19 PM.

  5. #155
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    5,373
    @KurtE
    Cool - going to have to copy that one in the test sketch I have running (the fonttest4 sketch you have in your copy from yesterday ).

    Oh by the way have CENTERING working for the most part, will push the changes up shortly. BTW don't need to do the define in the sketch anymore.

    EDIT: Not working yet for default font.

  6. #156
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    6,959
    Glad you have centering mostly working

    Note from the stuff before to get the font working. I did not put in the code to offset the rectangle by the current offset. Needless to say most all other graphic primitives have the offset/clip code in yet.

    Right now taking quick look at SPI speed ups.

  7. #157
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    6,959
    @mjs513 - Doing a first pass at SPI enhancments/speedups...

    Things like: hopefully now you can specify pins for SPI1 or SPI2 and it will work.

    Also failing when you ask if the CS pins is a hardware Serial pin and it is not, is not valid here as we are not using the hardware SPI CS support. Just digital writes... I did convert these over to grab the registers and directly set/clear...

    I also updated the begin method to allow you to pass in SPI speed..

    It runs... But no real speed change yet.

    Edit forgot to mention if anyone wants to play along: it is up in the branch: GIFW-HSPI

  8. #158
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    5,373
    @KurtE

    You lost me on this one. A little distracted right now watching SpaceX:
    Note from the stuff before to get the font working. I did not put in the code to offset the rectangle by the current offset. Needless to say most all other graphic primitives have the offset/clip code in yet.

  9. #159
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    6,959
    Quote Originally Posted by mjs513 View Post
    @KurtE

    You lost me on this one. A little distracted right now watching SpaceX:
    I keep meaning to watch... Have been busy burying the potato plants...
    What I mean that is needed is:

    Code:
    void RA8876_t3::fillRect(int16_t x, int16_t y, int16_t w, int16_t h,uint16_t color) {
    	x += _originx;
    	y += _originy;
    	int16_t x_end = x+w-1;
    	int16_t y_end = y+h-1;
    	if((x >= _displayclipx2)   || // Clip right
    		 (y >= _displayclipy2) || // Clip bottom
    		 (x_end < _displayclipx1)    || // Clip left
    		 (y_end < _displayclipy1))  	// Clip top 
    	{
    		// outside the clip rectangle
    		return;
    	}
    	if (x < _displayclipx1) x = _displayclipx1;
    	if (y < _displayclipy1) y = _displayclipy1;
    	if (x_end > _displayclipx2) x_end = _displayclipx2;
    	if (y_end > _displayclipy2) y_end = _displayclipy2;
    	drawSquareFill(x, y, x_end, y_end, color);
    }
    And then all of the other graphic primitives need something similar...

  10. #160
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    6,959
    Quick update: I believe that the RA8876(and maybe 5) are much more picky on SPI state. I tried hacking larger area of code to queue up the queue of data and the data did not show up correctly. (like more or less not at all).

    I have bypassed it and did a quick dirty change to see if it made a difference:
    Code:
    void RA8876_t3::lcdRegDataWrite(ru8 reg, ru8 data, bool finalize)
    {
      //write the register we wish to write to, then send the data
      //don't need to release _CS between the two transfers
      //ru16 _reg = (RA8876_SPI_CMDWRITE16 | reg);
      //ru16 _data = (RA8876_SPI_DATAWRITE16 | data);
      uint8_t buf[4] = {RA8876_SPI_CMDWRITE, reg, RA8876_SPI_DATAWRITE, data };
      startSend();
      //_pspi->transfer16(_reg);
      //_pspi->transfer16(_data);
      _pspi->transfer(buf, nullptr, 4);
      endSend(finalize);
    }
    It works and at 30mhz, Timing shows.

    Code:
    Setup
    
    Arial_14: 19ms
    ArialBold 14: 20ms
    ComicSansMS 14: 24ms
    Press anykey to continue
    
    DroidSans_14: 20ms
    Michroma_14: 25ms
    Press anykey to continue
    
    CRYSTAL_24: 98ms
    Press anykey to continue
    
    Chancery_24_Italic: 50ms
    OpenSans24: 345ms
    So it cut down some of the SPI gaps...

  11. #161
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    5,373
    Quote Originally Posted by KurtE View Post
    I keep meaning to watch... Have been busy burying the potato plants...
    What I mean that is needed is:
    …..
    And then all of the other graphic primitives need something similar...
    Got it. Also just looked at the RA8875 code and Sumotoy got sneaky with how he deals with clipping. He created functions like _rect_helper, _trangle_helper, etc that has the clipping so if you call drawTriangle or fillTriangle:
    Code:
    void RA8875::drawTriangle(int16_t x0, int16_t y0, int16_t x1, int16_t y1, int16_t x2, int16_t y2, uint16_t color)
    {
    	_triangle_helper(x0, y0, x1, y1, x2, y2, color, false);   //true for fill
    }

    The triangle helper has:
    Code:
    	if (x0 >= _width || x1 >= _width || x2 >= _width) return;
    	if (y0 >= _height || y1 >= _height || y2 >= _height) return;	
    	if (_portrait) {swapvals(x0,y0); swapvals(x1,y1); swapvals(x2,y2);}
    So going to be fun to add in clipping and origin shifting.

  12. #162
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    5,373
    Quote Originally Posted by KurtE View Post
    Quick update: I believe that the RA8876(and maybe 5) are much more picky on SPI state. I tried hacking larger area of code to queue up the queue of data and the data did not show up correctly. (like more or less not at all).

    I have bypassed it and did a quick dirty change to see if it made a difference:
    Code:
    void RA8876_t3::lcdRegDataWrite(ru8 reg, ru8 data, bool finalize)
    {
      //write the register we wish to write to, then send the data
      //don't need to release _CS between the two transfers
      //ru16 _reg = (RA8876_SPI_CMDWRITE16 | reg);
      //ru16 _data = (RA8876_SPI_DATAWRITE16 | data);
      uint8_t buf[4] = {RA8876_SPI_CMDWRITE, reg, RA8876_SPI_DATAWRITE, data };
      startSend();
      //_pspi->transfer16(_reg);
      //_pspi->transfer16(_data);
      _pspi->transfer(buf, nullptr, 4);
      endSend(finalize);
    }
    It works and at 30mhz, Timing shows.

    Code:
    Setup
    
    Arial_14: 19ms
    ArialBold 14: 20ms
    ComicSansMS 14: 24ms
    Press anykey to continue
    
    DroidSans_14: 20ms
    Michroma_14: 25ms
    Press anykey to continue
    
    CRYSTAL_24: 98ms
    Press anykey to continue
    
    Chancery_24_Italic: 50ms
    OpenSans24: 345ms
    So it cut down some of the SPI gaps...
    Very cool. Right now I am running at 50Mhz and got the same numbers as you did for the FontTest4 sketch.

  13. #163
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    6,959
    I may quit worrying about trying to speed up some of the SPI communications. I sort of now remember doing some of this exercise with RA8875 and punted...

    That is If I capture with Logic Analyzer the display of one of our font pages ...

    It looks like:
    Click image for larger version. 

Name:	screenshot.jpg 
Views:	4 
Size:	49.9 KB 
ID:	20393

    Click image for larger version. 

Name:	screenshot2.jpg 
Views:	10 
Size:	55.5 KB 
ID:	20394

    The first one gives sort of an overview look at the page. The part at the very start of the trace, is I believe the code that sets up to do a Page erase (fill Screen black)....
    The Red colored marked area to the right of it, is us doing a query loop waiting for the command to complete. Which I believe is something like 11.3ms

    The second one shows part of the data sent to initiate the update. Again one might be able to optimize the code especially on T3.x (or T4 with CS on PIN 9), to change the CS using the FIFO and remove those minor gaps... But compared to the wait... Not sure how much it is worth it.

  14. #164
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    5,373
    @KurtE
    I agree with you and the SPI speed now seems to make a difference when I change it. Before running at 50Mhz didn't seem to do anything even though it accepted it.

    Just pushed some more changes up to GITHUB and almost got centering working for default font. missing something though. Off a bit. Also copied over a bunch of clipping the way RA8875 did the graphic primitives except for a couple that I have to think about.

  15. #165
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    6,959
    @mjs513 - I think we can speed up a few of the SPI things a bit more, without needing to go down to SPI register level. Sort of like how I packed the two words into 4 bytes and did one transfer.

    But I before packing too many of these, may need to see in what circumstances the display requires the CS pin to change...

    Right now I am trying to play around with the PWM0 stuff. There was a test app (for some 8080 board) up on BuyDisplay.com, which supposedly sets up the PWM for the display, so I am trying to emulate this, first within test sketch... So far not working. So investigating.

    With these displays, keep wondering if we should try to make rotations of the display work? I don't think the registers for controlling reversing of bit orders is in both directions. Nor do I think they have the swap X, Y stuff like some of our other displays do. So if it is something should do at the interface level... I know it would be Royal PIA. Could probably do it with all of our higher level primitives, but probably not with built in fonts and the like.

    EDIT: Backlight control - Probably would help to look at PDF file for display.. There are hardware jumpers controlling this... Looks like setup for external.
    Last edited by KurtE; 06-01-2020 at 04:44 PM.

  16. #166
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    5,373
    @KurtE

    SPI is always challenging. PWM never played with it with these displays

    Next on my list was the screen rotation. Remember it being a challenge with the HDMI shield I was playing with back in the T4 beta days. Never could get it working right but maybe now is the time so off to that. But you know me I like doing coding from between 6-12 then I am off doing other stuff

  17. #167
    Senior Member
    Join Date
    Aug 2017
    Posts
    289
    @mjs513 and @ KurtE - I need a little direction here. I am so easily confused Who's branch of Ra8876Teeny should I be pulling from to keep up with you guy's? I have to take a break from MSC for a while. I am finally starting to understand and play with queuing, linked lists and such. Tonight I was trying out some of of the example sketches for Ra8876Teensy and realized I have no idea where you guy's are at with it. I did find a problem with drawing rectangles and round rectangles both filled and unfilled that I was able to figure out. But it's late and I have to be to work in four hours. i will post the updated code later

  18. #168
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    5,373
    @wwatson
    Sounds like you are having as much fun with MSC as we are with the RA8876

    Anyway the most current changes are at: https://github.com/mjs513/Ra8876Lite...X-ILI-Font-WIP. Interesting with the rectangle and rectangle fill. Both use drawSquare so let me know what the issue is?

  19. #169
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    6,959
    @mjs513 - Just did PR to you for adding backlight support. I no longer need the jumper to get the display to work...

    But had to change jumpers on the board.

  20. #170
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    5,373
    @KurtE
    Just did the merge. Not too complicated but a lot of work to get it working right.

    Just checked by display and it has the same config as yours but going to leave mine for awhile.

  21. #171
    Senior Member
    Join Date
    Aug 2017
    Posts
    289
    Quote Originally Posted by mjs513 View Post
    @wwatson
    Sounds like you are having as much fun with MSC as we are with the RA8876

    Anyway the most current changes are at: https://github.com/mjs513/Ra8876Lite...X-ILI-Font-WIP. Interesting with the rectangle and rectangle fill. Both use drawSquare so let me know what the issue is?
    Thank you for the link. Everything you guys have done so far seems to be working on my display as well at what appears to be 50 MHz. Cool

    I am running 'grahpics.ino' and anything to do with drawing rectangles or round rectangles is going completely off of the screen. Out of bounds so to speak. I was looking at 'drawRect(...)' in ILI9341_t3. I see the the way it is using 'drawFastHLine()' and 'drawFastVLine()' functions to draw a rectangle. Is this because there is no builtin draw square function? Anyway What I did to make it work was this:
    Code:
    // Draw a rectangle. Note: damages text color register
    void RA8876_t3::drawRect(int16_t x, int16_t y, int16_t w, int16_t h,uint16_t color) {
    
    	drawSquare(x, y, x+w-1, y+h-1, color);
    }
    
    // Draw a filled rectangle. Note: damages text color register
    void RA8876_t3::fillRect(int16_t x, int16_t y, int16_t w, int16_t h,uint16_t color) {
    
    	drawSquareFill(x, y, x+w-1, y+h-1, color);
    }
    
    // Draw a round rectangle. 
    void RA8876_t3::drawRoundRect(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t xr, uint16_t yr, uint16_t color) {
    	drawCircleSquare(x, y, x+w-1, y+h-1, xr, yr, color);
    }
    
    // Draw a filed round rectangle.
    void RA8876_t3::fillRoundRect(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t xr, uint16_t yr, uint16_t color) {
    	
    	
    	drawCircleSquareFill(x, y, x+w-1, y+h-1, xr, yr, color);
    }
    To this:
    Code:
    // Draw a rectangle. Note: damages text color register
    void RA8876_t3::drawRect(int16_t x, int16_t y, int16_t w, int16_t h,uint16_t color) {
    
    	drawSquare(x, y, w-1, h-1, color);
    }
    
    // Draw a filled rectangle. Note: damages text color register
    void RA8876_t3::fillRect(int16_t x, int16_t y, int16_t w, int16_t h,uint16_t color) {
    
    	drawSquareFill(x, y, w-1, h-1, color);
    }
    
    // Draw a round rectangle. 
    void RA8876_t3::drawRoundRect(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t xr, uint16_t yr, uint16_t color) {
    	drawCircleSquare(x, y, w-1, h-1, xr, yr, color);
    }
    
    // Draw a filed round rectangle.
    void RA8876_t3::fillRoundRect(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t xr, uint16_t yr, uint16_t color) {
    	
    	
    	drawCircleSquareFill(x, y, w-1, h-1, xr, yr, color);
    }
    This eliminated the addition of x+w and y+h which if x = 1023 and w = 1023 would equal 2048 and is obviously beyond the screen width of 1023. Same with y+h.

    Here is the 'graphics.ino' sketch I am using. Only change is commenting out the '#include "Ra8876_Lite.h"' line:
    Code:
    /*************************************************************** 
     * graphics.ino 
     * 
     * Basic graphics test for RA8876 based display
     ***************************************************************/
    #include "Arduino.h"
    //#include "Ra8876_Lite.h"
    #include "RA8876_t3.h"
    #define RA8876_CS 10
    #define RA8876_RESET 8
    #define BACKLITE 7 //External backlight control connected to this Arduino pin
    RA8876_t3 tft = RA8876_t3(RA8876_CS, RA8876_RESET); //Using standard SPI pins
    
    // Array of Simple RA8876 Basic Colors
    PROGMEM uint16_t myColors[] = {
    	0x0000,
    	0xffff,
    	0xf800,
    	0xfc10,
    	0x8000,
    	0x07e0,
    	0x87f0,
    	0x0400,
    	0x001f,
    	0x051f,
    	0x841f,
    	0x0010,
    	0xffe0,
    	0xfff0,
    	0x8400,
    	0x07ff,
    	0x87ff,
    	0x0410,
    	0xf81f,
    	0xfc1f,
    	0x8010,
    	0xA145
    };
    
    int interations = 0;
    
    // Draw random unfilled rectangle boxes
    void rectangles(uint16_t thickness) {
    	uint16_t x0, y0, x1, y1, c;
    	uint16_t j;
    
    	for(int i=0; i < interations; i++) {
    		x0 = (uint16_t)random(1,512);
    		y0 = (uint16_t)random(1,288);
    		x1 = (uint16_t)random(512,1023);
    		y1 = (uint16_t)random(288,575);
    		c = (uint16_t)random(21);
    		if(x0 > tft.width()) x0 = tft.width();
    		if(y0 > tft.height()) y0 = tft.height();
    		if(x1 > tft.width()) x1 = tft.width();
    		if(y1 > tft.height()) y1 = tft.height();
    		if(thickness > 0) {
    			for(j = 1; j <= thickness; j++) {
    				tft.drawRect(x0,y0,x1,y1,myColors[c]);
    				if(x0 <= tft.width())
    					x0++;
    				if(y0 <= tft.height())
    					y0++;
    				if(x1 > 0)
    					x1--;
    				if(y1 > 0)
    					y1--;
    			}
    		} else {
    			tft.drawRect(x0,y0,x1,y1,myColors[c]);
    		}
    	}
    	tft.fillStatusLine(myColors[11]);
    }
    
    // Draw random filled rectangle boxes
    void filledRectangles(void) {
    	uint16_t x0, y0, x1, y1, c;
    	for(int i=0; i< interations; i++) {
    		x0 = (uint16_t)random(1023);
    		y0 = (uint16_t)random(575);
    		x1 = (uint16_t)random(1023);
    		y1 = (uint16_t)random(575);
    		c = (uint16_t)random(21);
    		tft.fillRect(x0,y0,x1,y1,myColors[c+1]);
    	}
    	tft.fillStatusLine(myColors[11]);
    }
    
    // Draw random round rectangle boxes
    void rRectangles(uint16_t thickness) {
    	uint16_t x0, y0, x1, y1, xr, yr, c;
    	uint16_t j;
    
    	for(int i=0; i < interations; i++) {
    		x0 = (uint16_t)random(1,512);
    		y0 = (uint16_t)random(1,288);
    		x1 = (uint16_t)random(512,1023);
    		y1 = (uint16_t)random(288,575);
    		xr = 20; // Major Radius - Line Thickness must be less than
    		yr = 20; // Minor Radius - Major and Minor radiuses by at
    				 //				 - least half of xr and yr.
    		c = (uint16_t)random(21);
    		if(x0 > tft.width()) x0 = tft.width();
    		if(y0 > tft.height()) y0 = tft.height();
    		if(x1 > tft.width()) x1 = tft.width();
    		if(y1 > tft.height()) y1 = tft.height();
    		// Make sure major radius (xr) is less than x1 - x0
    		// Must be xr * 2 + 1 less than x1 - x0
    		// RA8876.pdf section 12.6 page 62
    		if((xr * 2 + 1) >= (x1 - x0))
    			xr = (x1 - x0) / 2 - 1;
    		// Same for minor radius (yr)
    		if((yr * 2 + 1) >= (y1 - y0))
    			yr = (y1 - y0) / 2 - 1;
    		if(thickness > 0) {
    			for(j = 1; j <= thickness; j++) {
    				tft.drawRoundRect(x0,y0,x1,y1,xr,yr,myColors[c]);
    				if(x0 <= tft.width())
    					x0++;
    				if(y0 <= tft.height())
    					y0++;
    				if(x1 > 0)
    					x1--;
    				if(y1 > 0 )
    					y1--;
    				if(xr > 0)
    					xr--;
    				if(yr > 0)
    					yr--;
    			}
    		} else {
    			tft.drawRoundRect(x0,y0,x1,y1,xr,yr,myColors[c]);
    		}
    	}
    	tft.fillStatusLine(myColors[11]);
    }
    
    // Draw random filled round rectangle boxes
    void filledRRectangles(void) {
    	uint16_t x0, y0, x1, y1, xr, yr, c;
    
    	for(int i=0; i < interations; i++) {
    		x0 = (uint16_t)random(1,512);
    		y0 = (uint16_t)random(1,288);
    		x1 = (uint16_t)random(512,1023);
    		y1 = (uint16_t)random(288,575);
    		xr = 20; // Major Radius
    		yr = 20; // Minor Radius
    		c = (uint16_t)random(21);
    
    		// Keep x,y within 1024x576 boundries
    		if(x0 > tft.width()) x0 = tft.width();
    		if(y0 > tft.height()) y0 = tft.height();
    		if(x1 > tft.width()) x1 = tft.width();
    		if(y1 > tft.height()) y1 = tft.height();
    		
    		// Make sure major radius (xr) is less than x1 - x0
    		// Must be xr * 2 + 1 less than x1 - x0
    		// RA8876.pdf section 12.6 page 62
    		if((xr * 2 + 1) >= (x1 - x0))
    			xr = (x1 - x0) / 2 - 1;
    		// Same for minor radius (yr)
    		if((yr * 2 + 1) >= (y1 - y0))
    			yr = (y1 - y0) / 2 - 1;
    		tft.fillRoundRect(x0, y0, x1, y1, xr, yr, myColors[c]);
    	}
    	tft.fillStatusLine(myColors[11]);
    }
    
    // Draw random circles
    void drawcircles(uint16_t thickness) {
    	uint16_t x0, y0, r, c;
    	int j;
    	for(int i=0; i < interations; i++) {
    		x0 = (uint16_t)random(1023);
    		y0 = (uint16_t)random(575);
    		r = (uint16_t)random(239);
    		c = (uint16_t)random(21);
    		if(x0-r <= 0)
    			x0 += (uint16_t)r;
    		if(y0-r <= 0)
    			y0 += (uint16_t)r;
    		if(x0+r >=  tft.width())
    			x0 = (uint16_t)(tft.width() - r);
    		if(y0+r >= tft.height())
    			y0 = (uint16_t)(tft.height() - r);
    		if(thickness > 0) {
    			for(j = 1; j <= thickness; j++) {
    				tft.drawCircle(x0, y0, r, myColors[c]);
    				if(r > 0)
    					r--;
    			}
    		} else {
    		tft.drawCircle(x0, y0, r, myColors[c]);
    		}
    		tft.drawCircle(x0, y0, r, myColors[c]);
    	}
    	tft.fillStatusLine(myColors[11]);
    }
    
    // Draw random filled circles
    void fillcircles(void) {
    	uint16_t x0, y0, r, c;
    	for(int i=0; i< interations; i++) {
    		x0 = (uint16_t)random(1023);
    		y0 = (uint16_t)random(575);
    		r = (uint16_t)random(239);
    		c = (uint16_t)random(21);
    		if(x0-r <= 0)
    			x0 += (uint16_t)r;
    		if(y0-r <= 0)
    			y0 += (uint16_t)r;
    		if(x0+r >=  tft.width())
    			x0 = (uint16_t)(tft.width() - r);
    		if(y0+r >= tft.height())
    			y0 = (uint16_t)(tft.height() - r);
    		tft.fillCircle(x0, y0, r, myColors[c]);
    	}
    	tft.fillStatusLine(myColors[11]);
    }
    
    // Draw random unfilled tritangles
    void drawTriangles(void) {
    	uint16_t x0, y0, x1, y1, x2, y2, c;
    	for(int i=0; i < interations; i++) {
    		x0 = (uint16_t)random(1023);
    		y0 = (uint16_t)random(575);
    		x1 = (uint16_t)random(1023);
    		y1 = (uint16_t)random(575);
    		x2 = (uint16_t)random(1023);
    		y2 = (uint16_t)random(575);
    		c = (uint16_t)random(21);
    		tft.drawTriangle(x0,y0,x1,y1,x2,y2,myColors[c+1]);
    	}
    	tft.fillStatusLine(myColors[11]);
    }
    
    // Draw random filled triangles
    void fillTriangles(void) {
    	uint16_t x0, y0, x1, y1, x2, y2, c;
    	for(int i=0; i < interations; i++) {
    		x0 = (uint16_t)random(1023);
    		y0 = (uint16_t)random(575);
    		x1 = (uint16_t)random(1023);
    		y1 = (uint16_t)random(575);
    		x2 = (uint16_t)random(1023);
    		y2 = (uint16_t)random(575);
    		c = (uint16_t)random(21);
    		tft.fillTriangle(x0,y0,x1,y1,x2,y2,myColors[c+1]);
    	}
    	tft.fillStatusLine(myColors[11]);
    }
    
    // Draw random unfilled ellipses
    void drawEllipses(void)
    {
    	int16_t  x0, y0, xr, yr;
    	uint16_t color;
    	for(int i=0; i < interations; i++) {
    		x0 = (uint16_t)random(1023);
    		y0 = (uint16_t)random(575);
    		xr = (uint16_t)random(239);
    		yr = (uint16_t)random(239);
    		color = (uint16_t)random(21);
    		if(x0-xr <= 0)
    			x0 += (uint16_t)xr;
    		if(y0-yr <= 0)
    			y0 += (uint16_t)yr;
    		if(x0+xr >=  tft.width())
    			x0 = (uint16_t)(tft.width() - xr);
    		if(y0+yr >= tft.height())
    			y0 = (uint16_t)(tft.height() - yr);
    		tft.drawEllipse(x0, y0, xr, yr, myColors[color]);
    	}
    	tft.fillStatusLine(myColors[11]);
    }
    
    // Draw random filled ellipses
    void fillEllipses(void)
    {
    	int16_t  x0, y0, xr, yr;
    	uint16_t color;
    	for(int i=0; i < interations; i++) {
    		x0 = (uint16_t)random(1023);
    		y0 = (uint16_t)random(575);
    		xr = (uint16_t)random(239);
    		yr = (uint16_t)random(239);
    		color = (uint16_t)random(21);
    		if(x0-xr <= 0)
    			x0 += (uint16_t)xr;
    		if(y0-yr <= 0)
    			y0 += (uint16_t)yr;
    		if(x0+xr >=  tft.width())
    			x0 = (uint16_t)(tft.width() - xr);
    		if(y0+yr >= tft.height())
    			y0 = (uint16_t)(tft.height() - yr);
    		tft.fillEllipse(x0, y0, xr, yr, myColors[color]);
    	}
    	tft.fillStatusLine(myColors[11]);
    	//timeOn(); // Turn on time/date display on status line
    }
    
    // Draw random Lines
    void drawlines(void) {
    	uint16_t x0, y0, x1, y1, c;
    
    	for(int i=0; i < interations; i++) {
    		x0 = (uint16_t)random(1,1023);
    		y0 = (uint16_t)random(1,575);
    		x1 = (uint16_t)random(1,1023);
    		y1 = (uint16_t)random(1,575);
    		c = (uint16_t)random(21);
    		if(x0 > tft.width()) x0 = tft.width();
    		if(y0 > tft.height()) y0 = tft.height();
    		if(x1 > tft.width()) x1 = tft.width();
    		if(y1 > tft.height()) y1 = tft.height();
    		tft.drawLine(x0,y0,x1,y1,myColors[c]);
    	}
    	tft.fillStatusLine(myColors[11]);
    }
    
    int i = 0;
    void setup() {
      //I'm guessing most copies of this display are using external PWM
      //backlight control instead of the internal RA8876 PWM.
      //Connect a Teensy pin to pin 14 on the display.
      //Can use analogWrite() but I suggest you increase the PWM frequency first so it doesn't sing.
      pinMode(BACKLITE, OUTPUT);
      digitalWrite(BACKLITE, HIGH);
        
    	tft.begin();
    	//initVT100();
      tft.setTextCursor(0,0);
    	tft.fillScreen(myColors[11]);
    	tft.setFontSize(1,false);
    }
    
    void loop() {
    	tft.printStatusLine(0,myColors[1],myColors[11],"Rectangles");
    	interations = 30000;
    	rectangles(0);
    	tft.fillScreen(myColors[11]);
    	delay(10);
    	tft.printStatusLine(0,myColors[1],myColors[11],"Rectangles 10 pixel line thickness");
    	interations = 4000;
    	rectangles(10);
    	tft.fillScreen(myColors[11]);
    	delay(10);
    	tft.printStatusLine(0,myColors[1],myColors[11],"Filled Rectangles");
    	interations = 4000;
    	filledRectangles();
    	tft.fillScreen(myColors[11]);
    	delay(10);
    	tft.printStatusLine(0,myColors[1],myColors[11],"Round Rectangles");
    	interations = 30000;
    	rRectangles(0);
    	tft.fillScreen(myColors[11]);
    	delay(10);
    	tft.printStatusLine(0,myColors[1],myColors[11],"Round Rectangles 10 pixel line thickness");
    	interations = 4000;
    	rRectangles(10);
    	tft.fillScreen(myColors[11]);
    	delay(10);
    	tft.printStatusLine(0,myColors[1],myColors[11],"Filled Round Rectangles");
    	interations = 4000;
    	filledRRectangles();
    	tft.fillScreen(myColors[11]);
    	delay(10);
    	tft.printStatusLine(0,myColors[1],myColors[11],"Circles");
    	interations = 30000;
    	drawcircles(0);
    	tft.fillScreen(myColors[11]);
    	delay(10);
    	tft.printStatusLine(0,myColors[1],myColors[11],"Circles 10 pixel circle thickness");
    	interations = 4000;
    	drawcircles(10);
    	tft.fillScreen(myColors[11]);
    	delay(10);
    	tft.printStatusLine(0,myColors[1],myColors[11],"Filled Circles");
    	interations = 4000;
    	fillcircles();
    	tft.fillScreen(myColors[11]);
    	delay(10);
    	tft.printStatusLine(0,myColors[1],myColors[11],"Triangles");
    	interations = 30000;
    	drawTriangles();
    	tft.fillScreen(myColors[11]);
    	delay(10);
    	tft.printStatusLine(0,myColors[1],myColors[11],"Filled Triangles");
    	interations = 4000;
    	fillTriangles();
    	tft.fillScreen(myColors[11]);
    	delay(10);
    	interations = 30000;
    	tft.printStatusLine(0,myColors[1],myColors[11],"Ellipses");
    	drawEllipses();
    	tft.fillScreen(myColors[11]);
    	delay(10);
    	tft.printStatusLine(0,myColors[1],myColors[11],"Filled Ellipses");
    	interations = 4000;
    	fillEllipses();
    	tft.fillScreen(myColors[11]);
    	delay(10);
    	tft.printStatusLine(0,myColors[1],myColors[11],"Lines");
    	interations = 100000;
    	drawlines();
    	tft.fillScreen(myColors[11]);
    	delay(10);
    }
    Hopefully I did not miss something
    Last edited by wwatson; 06-03-2020 at 02:34 AM. Reason: Double Quote: This is what happens when you are pulled away by family:)

  22. #172
    Member MorganS's Avatar
    Join Date
    Apr 2015
    Location
    Northern Nevada
    Posts
    61
    The original code expects to send screen coordinates for top-left and bottom-right corners to drawSquare().

    If drawSquare() is expecting top-left and width&height then the maths is wrong. You don't need to subtract one from W & H.

  23. #173
    Senior Member
    Join Date
    Aug 2017
    Posts
    289
    Quote Originally Posted by MorganS View Post
    The original code expects to send screen coordinates for top-left and bottom-right corners to drawSquare().

    If drawSquare() is expecting top-left and width&height then the maths is wrong. You don't need to subtract one from W & H.
    I did miss that. If choosing a random number between 0 and 1023 for width you would not need to subtract 1 from the width. The other thing that pop's into my mind is if the random(...) function would actually return a 0 value for a minimum number to get the full range of 1024 pixels.

  24. #174
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    5,373
    Quote Originally Posted by wwatson View Post
    I did miss that. If choosing a random number between 0 and 1023 for width you would not need to subtract 1 from the width. The other thing that pop's into my mind is if the random(...) function would actually return a 0 value for a minimum number to get the full range of 1024 pixels.
    Think that was my fault. I was adding some clipping tests and changing things around. Think I messed up and doing the restructuring. Going to put it back to w, h and fix the test in drawSquare etc.

  25. #175
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    5,373
    @wwatson - @MorganS -@KurtE

    Just pushed some changes up to the font wip branch: https://github.com/mjs513/Ra8876Lite...X-ILI-Font-WIP

    1. Has @KurtE's PWM Backlite code incorporated
    2. Fixed clipping for rectangle calls
    3. Fixed graphics.ino: the current sketch graphics.ino sketch uses absolute coordinates for drawing rectangles as opposed to x,y,w,h. That is now fixed in the sketch
    4. added a Rotate() function to rotate the screen 90degs ccw. However, its not working. It appears when I write to MACR register it doesn't retain the changed value so its always using the default value. Not sure whats going on. The code is based on an example I got from RAIO when I asked them a question on screen rotation.
    5. I also added a simple test sketch for rotation.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •