Go Down

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

ZinggJM

Maybe this leads back to the roots of this shield:

http://www.electrodragon.com/product/3-2-tft-lcd-arduino-adapter-shield/

following the links of this product leads to the same schematics.

I asked Auntie Google for "tft adapter shield Arduino".

The nice thing about the Arduino World is that its based on Open Source, not only software, but also hardware. But this can have strange side-effects, such as "missing pressure" to hide the source.

Jean-Marc
No personal message please; any question may be useful for other users. Use code tags for code. Make links clickable with URL tags. Provide links to the product in question.

ZinggJM

Hi David, I need your help

My 7inch display with SSD1963 works fine with the modifications applied to MCUFRIEND_kbv; rotation works correctly.

It also works with my GxCTRL_SSD1963 class, except for rotation.
I have not found how to achieve Portrait mode.

I added Serial.print() output to MCUFRIEND_kbv.cpp to see the command sent for rotation.
But the commands 0x33 or 0x20 seem not to be sufficient, something seems missing.
Should I look at the scrolling support; I do not use scrolling for now.

Of course I should look for the SSD1963 specs, but maybe you can give me a hint.

Thank you

Jean-Marc
No personal message please; any question may be useful for other users. Use code tags for code. Make links clickable with URL tags. Provide links to the product in question.

david_prentice

You can handle the rotations on a SSD1963 with the FLIP_Vert and FLIP_Horiz bits in reg(0x36).
Leave MX, MY alone.   Unless you want to draw a Font upside down or backwards.

The MCUFRIEND_kbv rotation code is very messy.   Controllers behave differently.   I do intend to simplify it.

Have you implemented RD yet?
I bet that most of your initialisation is setting registers to their Reset default values.
Most MIPI chips only require VCOM and Power settings.   And their default values will generally work pretty well.

If you have the ILI9806 wired to the same interface as the SSD1963,   I will add a case(0x9806) to begin() if you care to test it.

David.

ZinggJM

Hi David

Great, your help came very quick!

I will try this soon, after a break.

Read is next on my agenda, and of course I will look how it is done in MCUFRIEND_kbv.
Automatic support for connected controller is not high on my priority list, for this we have your library, but I intend to do a ReadReg variant for GxIO.

Thank you for your support and inspiring communication.

Jean-Marc
No personal message please; any question may be useful for other users. Use code tags for code. Make links clickable with URL tags. Provide links to the product in question.

david_prentice

Here is a case for begin()
Code: [Select]

#define SUPPORT_9806
#ifdef SUPPORT_9806
    case 0x9806:
        _lcd_capable = AUTO_READINC | MIPI_DCS_REV1 | MV_AXIS | READ_24BITS;
        // from ZinggJM
        static const uint8_t ILI9806_regValues[] PROGMEM = {
            (0xFF), 3, /* EXTC Command Set enable register*/ 0xFF, 0x98, 0x06,
            (0xBA), 1, /* SPI Interface Setting*/0xE0,
            (0xBC), 21, /* GIP 1*/0x03, 0x0F, 0x63, 0x69, 0x01, 0x01, 0x1B, 0x11, 0x70, 0x73, 0xFF, 0xFF, 0x08, 0x09, 0x05, 0x00, 0xEE, 0xE2, 0x01, 0x00, 0xC1,
            (0xBD), 8, /* GIP 2*/0x01, 0x23, 0x45, 0x67, 0x01, 0x23, 0x45, 0x67,
            (0xBE), 9, /* GIP 3*/0x00, 0x22, 0x27, 0x6A, 0xBC, 0xD8, 0x92, 0x22, 0x22,
            (0xC7), 1, /* Vcom*/0x1E,
            (0xED), 3, /* EN_volt_reg*/0x7F, 0x0F, 0x00,
            (0xC0), 3, /* Power Control 1*/0xE3, 0x0B, 0x00,
            (0xFC), 1, 0x08,
            (0xDF), 6, /* Engineering Setting*/0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
            (0xF3), 1, /* DVDD Voltage Setting*/0x74,
            (0xB4), 3, /* Display Inversion Control*/0x00, 0x00, 0x00,
            (0xF7), 1, /* 480x854*/0x81,
            (0xB1), 3, /* Frame Rate*/0x00, 0x10, 0x14,
            (0xF1), 3, /* Panel Timing Control*/0x29, 0x8A, 0x07,
            (0xF2), 4, /*Panel Timing Control*/0x40, 0xD2, 0x50, 0x28,
            (0xC1), 4, /* Power Control 2*/0x17, 0x85, 0x85, 0x20,
            (0xE0), 16, 0x00, 0x0C, 0x15, 0x0D, 0x0F, 0x0C, 0x07, 0x05, 0x07, 0x0B, 0x10, 0x10, 0x0D, 0x17, 0x0F, 0x00,
            (0xE1), 16, 0x00, 0x0D, 0x15, 0x0E, 0x10, 0x0D, 0x08, 0x06, 0x07, 0x0C, 0x11, 0x11, 0x0E, 0x17, 0x0F, 0x00,
            (0x35), 1, /*Tearing Effect ON*/0x00,
        };
        table8_ads = ILI9806_regValues, table_size = sizeof(ILI9806_regValues);
        p16 = (int16_t *) & HEIGHT;
        *p16 = 480;
        p16 = (int16_t *) & WIDTH;
        *p16 = 854;
        break;
#endif


UNTESTED.  

If the colours are inverted,  add the REV_SCREEN attribute.

David.

Edit.  I just noticed that EXTC shared the same magic value as TFTLCD_DELAY8.
Code: [Select]

#define TFTLCD_DELAY8 0x7F   //very unlikely to be a valid MIPI register.

ZinggJM

#1445
Mar 21, 2017, 01:38 pm Last Edit: Mar 21, 2017, 01:47 pm by ZinggJM Reason: added info
You can handle the rotations on a SSD1963 with the FLIP_Vert and FLIP_Horiz bits in reg(0x36).
Leave MX, MY alone.   Unless you want to draw a Font upside down or backwards.

...

If you have the ILI9806 wired to the same interface as the SSD1963,   I will add a case(0x9806) to begin() if you care to test it.

David.
I tried to understand. FLIP_Vert and FLIP_Horiz are defined in MCUFRIEND_kbv.cpp, but not used there.
Aha - I forgot to look in the include files, there I might find the values to write to reg(0x36).
And here I learn something I was not aware of clearly so far, the value in a command (CD low) is just a register address, therefore the signal line is also called RS.

I still should consult the SSD1963 specs, sometimes to be lazy takes more time than just do it, and I might look in UTFT; UTFT takes PORTRAIT in the begin method, shows portrait mode, but window size is not correct for my SSD1963 tft. But it would also reveal how portrait can be achieved.

I do have a "frozen" wiring for my Tiky display on DUE, DuPont lines fixed with the long tail connectors on both sides, but this nearly parallel connection needs an appropriate softeare wiring, in one of my GxIO subclasses. So I can't check directly with MCUFRIEND_kbv.

Ok, maybe I just need to put the MEGA shield in between.

Jean-Marc
No personal message please; any question may be useful for other users. Use code tags for code. Make links clickable with URL tags. Provide links to the product in question.

ZinggJM

UTFT swaps parameter in setXY so many times, that my head is still rotating. So maybe I need to switch x and y coordinates, and reverse x0 and x1 and y0 and y1, and subtract from width and height, and...

So there are many combinations to try, to keep me busy.
No personal message please; any question may be useful for other users. Use code tags for code. Make links clickable with URL tags. Provide links to the product in question.

david_prentice

If your wiring is clear,   I will write the appropriate SPECIAL.
Which AVR,  ARM are you using?

ZinggJM

If your wiring is clear,   I will write the appropriate SPECIAL.
Which AVR,  ARM are you using?
Sorry, I just somehow go into overload. My head stopped spinning, but now I need time to search and study SSD1963 specs.

I am used to get into trouble with topology problems, and here I have two.

1. UTFT: this indicates that the display allows start and end coordinates reverted to write in reversed direction.

2. The mega shield remaps pins for the 7inch SSD1963 tft, but I have no wiring from this to my Tiky.

If you want to add software wiring to MCUFRIEND_kbv for one of my wirings for a test, this would be nice.
I will put my GxIO classes for Tiky on GitHub, but need to fix names and do  cleanup, as soon as I am out of overload. I have versions for DUE and 2 STM32 boards, and my BluePill wiring. The pin mapping is documented in the source files.

I you know the values to write to 0x36 for portrait mode of SSD1983, this would help.

Jean-Marc
No personal message please; any question may be useful for other users. Use code tags for code. Make links clickable with URL tags. Provide links to the product in question.

david_prentice

I looked t your GxIO_HVGAOnDue.cpp file and your mapping is exactly the same as the Mega.   i.e. my USE_MEGA_16BIT_SHIELD

If you just give me your Due mapping for the ILI9806,  I will write the SPECIAL.

David.

ZinggJM

I just added my TIKY io classes to GitHub, without re-test.
Unfortunately only the BluePill version has detailed pin mapping information yet.

Jean-Marc
No personal message please; any question may be useful for other users. Use code tags for code. Make links clickable with URL tags. Provide links to the product in question.

david_prentice

Which STM32 is your Tiky plugged into?
Or is it plugged into the Due?

I don't mind writing one SPECIAL.   I don't want to have to write three.

What port is /CS mapped to?
Life is simpler if you say PC13 or PA06.   Then I know which STM32 PORT pin you are using.

Arduinos have a physical Shield header.   The world knows that digital#13 is PB5 on a Uno, PB7 on a Mega, PB27 on a Due,  PA05 on a Nucleo.

David.

david_prentice

Here is a SPECIAL for a BluePill

Code: [Select]

#define XINGGJM_BLUEPILL
...
// #################################### XINGIJM #######################################
#elif defined(__STM32F1__) && defined(XINGGJM_BLUEPILL) // Uno Shield on BluePill
#warning Uno Shield on XINGJM_BLUEPILL
#define USES_16BIT_BUS
// be wise to clear all four mode bits properly.
#define GROUP_MODE(port, reg, mask, val)  {port->regs->reg = (port->regs->reg & ~(mask)) | ((mask)&(val)); }
#define GP_OUT(port, reg, mask)           GROUP_MODE(port, reg, mask, 0x33333333)
#define GP_INP(port, reg, mask)           GROUP_MODE(port, reg, mask, 0x44444444)

#define RD_PORT GPIOB
#define RD_PIN  13
#define WR_PORT GPIOB
#define WR_PIN  10
#define CD_PORT GPIOB
#define CD_PIN  12
#define CS_PORT GPIOB
#define CS_PIN  11
#define RESET_PORT GPIOB
#define RESET_PIN  1

// configure macros for the data pins
#define write_16(d) { \
        GPIOA->regs->BSRR = (0x81FE) << 16; \
        GPIOB->regs->BSRR = (0xC079) << 16; \
        GPIOA->regs->BSRR = 0 \
                            | (((d) & (1<<3)) << 4) \
                            | (((d) & (1<<4)) << 4) \
                            | (((d) & (1<<5)) << 2) \
                            | (((d) & (1<<6)) << 9) \
                            | (((d) & (1<<7)) >> 2) \
                            | (((d) & (1<<9)) >> 5) \
                            | (((d) & (1<<11)) >> 8) \
                            | (((d) & (1<<13)) >> 11) \
                            | (((d) & (1<<15)) >> 14); \
        GPIOB->regs->BSRR = 0 \
                            | (((d) & (1<<0)) << 14) \
                            | (((d) & (1<<1)) >> 1) \
                            | (((d) & (1<<2)) << 13) \
                            | (((d) & (1<<8)) >> 5) \
                            | (((d) & (1<<10)) >> 6) \
                            | (((d) & (1<<12)) >> 7) \
                            | (((d) & (1<<14)) >> 8); \
    }

#define read_16 (          (((GPIOB->regs->IDR & (1<<14)) >> 14) \
                            | ((GPIOB->regs->IDR & (1<<0)) << 1) \
                            | ((GPIOB->regs->IDR & (1<<15)) >> 13) \
                            | ((GPIOA->regs->IDR & (1<<7)) >> 4) \
                            | ((GPIOB->regs->IDR & (1<<8)) >> 4) \
                            | ((GPIOA->regs->IDR & (1<<6)) >> 1) \
                            | ((GPIOA->regs->IDR & (1<<15)) >> 9) \
                            | ((GPIOA->regs->IDR & (1<<5)) << 2) \
                            | ((GPIOB->regs->IDR & (1<<3)) << 5) \
                            | ((GPIOA->regs->IDR & (1<<4)) << 5) \
                            | ((GPIOB->regs->IDR & (1<<4)) << 6) \
                            | ((GPIOA->regs->IDR & (1<<3)) << 8) \
                            | ((GPIOB->regs->IDR & (1<<5)) << 7) \
                            | ((GPIOA->regs->IDR & (1<<2)) << 11) \
                            | ((GPIOB->regs->IDR & (1<<6)) << 8) \
                            | ((GPIOA->regs->IDR & (1<<1)) << 14)))

//                                          PA15,PA8                         PA7-PA1                       PB15,PB14                     PB6-PB3,PB0
#define setWriteDir() {GP_OUT(GPIOA, CRH, 0xF000000F); GP_OUT(GPIOA, CRL, 0xFFFFFFF0); GP_OUT(GPIOB, CRH, 0xFF000000); GP_OUT(GPIOB, CRL, 0x0FFFF00F); }
#define setReadDir()  {GP_INP(GPIOA, CRH, 0xF000000F); GP_INP(GPIOA, CRL, 0xFFFFFFF0); GP_INP(GPIOB, CRH, 0xFF000000); GP_INP(GPIOB, CRL, 0x0FFFF00F); }

#define write8(x)     { write16(x & 0xFF); }
#define write16(x)    { write_16(x); WR_ACTIVE; WR_STROBE; WR_IDLE; WR_IDLE; }
#define READ_16(dst)  { RD_STROBE; RD_ACTIVE; RD_ACTIVE; RD_ACTIVE; RD_ACTIVE; dst = read_16(); RD_IDLE; RD_IDLE; RD_IDLE; }
#define READ_8(dst)   { READ_16(dst); dst &= 0xFF; }

#define PIN_HIGH(port, pin)   (port)->regs->BSRR = (1<<(pin))
//#define PIN_LOW(port, pin)    (port)->regs->BSRR = (1<<((pin)+16))
#define PIN_LOW(port, pin)    (port)->regs->ODR &= ~(1<<(pin))
#define PIN_OUTPUT(port, pin) gpio_set_mode(port, pin, GPIO_OUTPUT_PP)   //50MHz push-pull only 0-7
#define PIN_INPUT(port, pin)  gpio_set_mode(port, pin, GPIO_INPUT_FLOATING)   //digital input



These are pretty fiddly to do.  Especially when you choose random port pins.   
I am not happy with using the Maple gpio_set_mode()

Please let me know how it goes.

David.

ZinggJM

David

Did we misunderstand each other?

My Tiky display works with my GxCTRL_ILI9806 with all three GxIO classes for Tiky, even a fourth one, the STM32F103V board which is made for the interface of this display. For the other three I have kept DuPont wiring cables.

I though you want me to test your ILI9806 additions to MCUFRIEND_kbv on Arduino DUE.

But I decided that rotation support in my GxCTRL_ILI1963 class is what I want to solve first.
I must learn not to rush to put additions on GitHub before I finished it, just because I thought in might be interesting to one of my favorite display gurus.

Jean-Marc
No personal message please; any question may be useful for other users. Use code tags for code. Make links clickable with URL tags. Provide links to the product in question.

david_prentice

I think that we "almost" understand each other.

1.  You asked about Rotations in #1454.  I answered in #1455

2.  I wrote the case 0x9806: for MCUFRIEND_kbv to support your ILI9806.  (assuming that you connected with the same 16-bit i/f as SSD1963)

3.  Your ILI9806 (Tiky) has a different i/f mapping.

4.  I wrote a SPECIAL for the BluePill.   I am guessing that the Tiky is currently connected to the STM32F103C8T6 BluePill.

5.  I am sure that it takes a long time to rewire the Tiky for the Big STM32 or the Due.

6.  I might write a SPECIAL for the Due.   The real mystery is:  why do you use random pins for the data bus?    Running a Mega Shield on a Due forces mixed ports.   But once you choose a wiring scheme,  why not stick to it?

Is there something that you don't understand with reg(0x36) on a MIPI controller like SSD1963 (or ILI9806)?
I want to avoid maths and transformations a la UTFT.   i.e. the same drawing code works in all 4 aspects.

David.

Go Up