Go Down

Topic: MCUFRIEND_kbv Library for Uno 2.4, 2.8, 3.5, 3.6, 3.95 inch mcufriend Shields (Read 357268 times) previous topic - next topic

francosalda

hi, how can i rotate only the text?
because I kept all the texts turned around the way I wanted

david_prentice

I could render the text right to left if that is what you really want.
Most European languages write left to right.

Your name does not look very Jewish or Arabic.
What text directions do you need?
Which controllers are you using?

David.

francosalda

i need to go from the first text(1st line) to the second text (2nd line) , like this image :



It would be great if the library included a function like SetTextRotation(angle) ..

I'm using a Touch Display ID :0x2053
Driver  :SPFD5408 display


...all the functions that I can use are those that are described in the library inside the .h right?

david_prentice

I am impressed that someone else has an ID=0x2053 controller.
I have no idea what make it is.   It works a little differently from all other MIPI controllers.

If you simply want to mirror a small area of the screen,  you might just as well use the readGRAM() method to read the screen memory.   And write it back in a different direction.

If your native language is written right to left,   I would add the appropriate methods to the Library.
In this case it seems more appropriate to just write a regular function in a sketch.

Can I ask WHY?

David.

david_prentice

I still can't understand why you want to have mirrored text.
Here is an example sketch tested on an SPI chip.   Change the include and class to MCUFRIEND_kbv

Code: [Select]

#include <ILI9341_kbv.h>
ILI9341_kbv tft;
//#include <MCUFRIEND_kbv.h>
//MCUFRIEND_kbv tft;

#include "Fonts/FreeSerif18pt7b.h"

// Assign human-readable names to some common 16-bit color values:
#define BLACK   0x0000
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF

void reverse_pixels(uint16_t *buf, int n)
{
    for (int i = 0; i < --n; i++) {
        uint16_t t = buf[i];
        buf[i] = buf[n];
        buf[n] = t;
    }
}

void mirror_rect(int x, int y, int w, int h, int dstx, int dsty, int dir)
{
    uint16_t pixbuf[320];   //very BIG array to put on the stack
    if (dir == 0) {
        for (int col = 0; col < w; col++) {
            tft.readGRAM(x + col, y, pixbuf, 1, h);
            reverse_pixels(pixbuf, h);
            tft.setAddrWindow(dstx + col, dsty, dstx + col, dsty + h - 1);
            tft.pushColors(pixbuf, h, 1);
        }
    } else {
        for (int row = 0; row < h; row++) {
            tft.readGRAM(x, y + row, pixbuf, w, 1);
            reverse_pixels(pixbuf, w);
            tft.setAddrWindow(dstx, dsty + row, dstx + w - 1, dsty + row);
            tft.pushColors(pixbuf, w, 1);
        }
    }
    // restore the whole screen window
    tft.setAddrWindow(0, 0, tft.width() - 1, tft.height() - 1);
}

void print_mirror(char *msg, int x, int y, int dir)
{
    int16_t x1, y1, w, h;
    tft.setCursor(x, y);
    tft.print(msg);
    tft.getTextBounds(msg, x, y, &x1, &y1, &w, &h);
    mirror_rect(x1, y1, w, h, x1, y1, dir);
}

void setup()
{
    tft.begin(tft.readID());
    tft.setRotation(1);
    tft.fillScreen(BLACK);
    tft.setFont(&FreeSerif18pt7b);
    char msg[] = "Mirror Me";
    int16_t x, y, x1, y1, w, h;
    tft.setCursor(x = 0, y = 24);
    tft.print(msg);
    tft.getTextBounds(msg, x, y, &x1, &y1, &w, &h);
    mirror_rect(x1, y1, w, h, x1, y1 + 50, 0);  //vertical mirror
    mirror_rect(x1, y1, w, h, x1, y1 + 100, 1); //horiz mirror

    char buf[80];
    sprintf(buf, "x=%d, y=%d, x1=%d, y1=%d, w=%d, h=%d",
            x, y, x1, y1, w, h);
    tft.setFont(NULL);             //use default 7x5 mono font
    tft.setCursor(0, 220);
    tft.println(buf);

    tft.setFont(&FreeSerif18pt7b); //restore the FreeFont

    delay(10000);
}

void loop()
{
    tft.fillScreen(RED);
    // Woo-hoo.  It even flips a 2-line block of text
    print_mirror("Vertical Mirror.\nSecond line.", 0, 50, 0);
    print_mirror("Horizontal Mirror.", 0, 150, 1);
    print_mirror("Some offset text.", 50, 200, 1);
    delay(5000);
}

Note that pixbuf[320] is a VERY big buffer to put on the stack.   You could make it global (or smaller)
You only need it to be as big as your largest rectangle dimension.

David.

tbillion

is there a tutorial somewhere on how to make a SPECIAL file to change the pin mapping for the D0 to D7 on an ili9325 powered display?

david_prentice

No.   You can read the source code for yourself.

If you test your pin mapping with the LCD_ID_readreg sketch and post your #defines,
I will write the Special for you.    Please say which Target board you need.

Note that digital#0 is very problematic on the Data bus.    The  USB or MAX232 bridge will b*gger up any Read operation.    It does "work" as write-only but I would not advise it.

David.

tbillion

Code: [Select]
Read Registers on MCUFRIEND UNO shield
controllers either read as single 16-bit
e.g. the ID is at readReg(0)
or as a sequence of 8-bit values
in special locations (first is dummy)

reg(0x0000) 00 00 ID: ILI9320, ILI9325, ILI9335, ...
reg(0x0004) 00 00 80 00 Manufacturer ID
reg(0x0009) 00 00 00 00 00 Status Register
reg(0x000A) 08 08 Get Power Mode
reg(0x000C) 66 66 Get Pixel Format
reg(0x0061) 00 00 RDID1 HX8347-G
reg(0x0062) 00 00 RDID2 HX8347-G
reg(0x0063) 00 00 RDID3 HX8347-G
reg(0x0064) 00 00 RDID1 HX8347-A
reg(0x0065) 00 00 RDID2 HX8347-A
reg(0x0066) 00 00 RDID3 HX8347-A
reg(0x0067) 00 00 RDID Himax HX8347-A
reg(0x0070) 00 00 Panel Himax HX8347-A
reg(0x00A1) 00 00 00 00 00 RD_DDB SSD1963
reg(0x00B0) 00 00 RGB Interface Signal Control
reg(0x00B4) 0C 0C Inversion Control
reg(0x00B6) 02 02 08 08 08 Display Control
reg(0x00B7) 00 00 Entry Mode Set
reg(0x00BF) 00 00 00 00 00 00 ILI9481, HX8357-B
reg(0x00C0) 44 44 44 10 10 00 00 00 00 Panel Control
reg(0x00C8) 00 00 00 00 00 00 00 00 00 00 00 00 00 GAMMA
reg(0x00CC) 00 00 Panel Control
reg(0x00D0) 00 00 00 Power Control
reg(0x00D2) 80 80 00 00 00 NVM Read
reg(0x00D3) 00 00 00 00 ILI9341, ILI9488
reg(0x00D4) 01 01 53 10 Novatek ID
reg(0x00DA) 00 00 RDID1
reg(0x00DB) 80 80 RDID2
reg(0x00DC) 00 00 RDID3
reg(0x00E0) 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 GAMMA-P
reg(0x00E1) 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 GAMMA-N
reg(0x00EF) 00 00 00 00 00 00 ILI9327
reg(0x00F2) F1 F1 54 A5 24 1E 44 90 02 2C 2C 32 Adjust Control 2
reg(0x00F6) 00 00 3A 00 Interface Control



Code: [Select]
#define LCD_RST 29
#define LCD_CS 31
#define LCD_RS A2
#define LCD_WR A1
#define LCD_RD 33

#define LCD_D0 49
#define LCD_D1 47
#define LCD_D2 45
#define LCD_D3 43
#define LCD_D4 41
#define LCD_D5 39
#define LCD_D6 37
#define LCD_D7 35


running on a mega just in case anyone didnt know :) Thanks!

david_prentice

Are you serious?  Looking at the pin mapping:
Code: [Select]

#define LCD_RST 29 //PA7
#define LCD_CS 31 //PC5
#define LCD_RS A2 //PF2
#define LCD_WR A1 //PF1
#define LCD_RD 33 //PC4

#define LCD_D0 49 //PL0
#define LCD_D1 47 //PL2
#define LCD_D2 45 //PL4
#define LCD_D3 43 //PL6
#define LCD_D4 41 //PG0
#define LCD_D5 39 //PG2
#define LCD_D6 37 //PC0
#define LCD_D7 35 //PC2

Yes,   I can write the SPECIAL.   The performance will be extremely painful.   Is there a good reason for your choice?

Placing the Data bus on PORTA would give you excellent performance e.g. far better than the Uno.

David.

tbillion

if i have to stick the data all on one port i would prefer portL vs PortA even though i am aware that port A is technically for DMA, however if you feel that the improvement in performance would be worth it i would take port A and move everything else elsewhere, except for the 2 pins that have to be plugged into the analog i am trying to condense all the pins onto the big header on the Mega, reasoning on this is, i need the PWM on the lower number pins and the other functions they provide for the most part that big 32 pin port is wasted, i mainly just use it for hardcore digital things so it seemed logical to move the digital screen to the bottom, as for the pins i selected there it was just what i plugged it into, i was unaware one could gain any performance boost by putting it on one pin or another. You are the guru when it comes to these which is why i had asked you, i love your library, because of it i only buy these screens now. ive figured out how to get them on 300mm of wire so they can be mounted apart from the mega and it makes them work very well. 

david_prentice

The ATmega2560 does not have DMA.    It does have an external address bus with PORTA, PORTC but Arduinos don't use it.

It makes no little difference to performance if you use PORTA or PORTL as the data bus.
Mapping random pins to random bits on a data bus cripples performance.

I will do you a SPECIAL for:
Code: [Select]


#define LCD_RST 29 //PA7
#define LCD_CS 31 //PC5
#define LCD_RS A2 //PF2
#define LCD_WR A1 //PF1
#define LCD_RD 33 //PC4

#define LCD_D0 49 //PL0
#define LCD_D1 48 //PL1
#define LCD_D2 47 //PL2
#define LCD_D3 46 //PL3
#define LCD_D4 45 //PL4
#define LCD_D5 44 //PL5
#define LCD_D6 43 //PL6
#define LCD_D7 42 //PL7


Here it is:
Code: [Select]

// ################## MEGA SPECIAL for Tbillion ###############
#define USE_TBILLION
...
#elif defined(__AVR_ATmega2560__)  && defined(USE_TBILLION)      //
#warning SPECIAL for USE_TBILLION
#define RD_PORT PORTC
#define RD_PIN  4
#define WR_PORT PORTF
#define WR_PIN  1
#define CD_PORT PORTF
#define CD_PIN  2
#define CS_PORT PORTC
#define CS_PIN  5
#define RESET_PORT PORTA
#define RESET_PIN  7

#define LMASK         0xFF
#define write_8(x)   { PORTL = x; }
#define read_8()      ( PINL )
#define setWriteDir() { DDRL |=  LMASK; }
#define setReadDir()  { DDRL &= ~LMASK; }
#define write8(x)     { write_8(x); WR_STROBE; }
#define write16(x)    { uint8_t h = (x)>>8, l = x; write8(h); write8(l); }
#define READ_8(dst)   { RD_STROBE; dst = read_8(); RD_IDLE; }
#define READ_16(dst)  { uint8_t hi; READ_8(hi); READ_8(dst); dst |= (hi << 8); }

#define PIN_LOW(p, b)        (p) &= ~(1<<(b))
#define PIN_HIGH(p, b)       (p) |= (1<<(b))
#define PIN_OUTPUT(p, b)     *(&p-1) |= (1<<(b))


Untested.   Let me know if you have a problem.

David.

Bricki

Hi David,

beside the first UART I want to use the second UART on my Teensy 3.2 for communication purpose. Unfortunately the Pins 9 (Rx2) and 7 (Rx3) are both occupied by the mcufriendlibrary for D7 and D9 in 8bit mode.

Do you see a chance, that I can at least use D11 instead of D9 for the TFT and get UART2 free to use?

At which position do I have to make the changes?

Thanks
Peter

david_prentice

Take a long hard look at the pins available on a Teensy3.2
D11 is used by SPI e.g. an SD Card.

I provide the driver for using the official Arduino pins e.g. if you plug a Shield into the SparkFun adapter.
I suggest that you stick to this wiring,   but it is easy enough to change to a "well thought and chosen" alternative scheme.

I will write the SPECIAL for you.   When you have tested the wiring scheme with LCD_ID_readreg sketch.

David.

Bricki

OK, got it. What about D13? There's no special function at this Pin except the LED. Or D20/A6 could also be possible, if D13 is not a good choice in your opinion.

Thanks
Peter

david_prentice


Go Up