Need help with 7 Inch LCD with SSD1963 on Blue pill

Hi,
I have a 40 pins 7 inch tft lcd with SSD1963 driver and a standard blue pill STM32F103C8T6. I tried using the Special from Mr David and modified my connection accordingly as follows

LCD : DO ------------------,D15 , RD,WR,RS,CS , RST
BLUE PILL: B0,B1 ,A15,B3,.......,B15 , A0, A1, A2, A3, A8

I am using those cheap china ST-LinkV2 to upload the graphictest.kbv from MCUfriend.
After using the SPECIAL written for one PIONSCOR by David, I compile and uploaded without error.
However, the screen of my LCD is not responding.
The LCD is not an issue as it is working fine on a Mega board with my rewiring running on UTFT library code.

Has anybody tried using a 800x480 tft with SSD1963 on a blue pill?

Any help is appreciated.

I found that SPECIAL in extras/unused/mcufriend_special_2.h

#elif defined(USE_PIONSCOR_BLUEPILL) && (defined(__STM32F1__) || defined(STM32F103xB)) // MAPLECORE or STM32CORE 
#warning SSD1963 on USE_PIONSCOR_BLUEPILL
...

When you build, you should see an ORANGE warning : SSD1963 on USE_PIONSCOR_BLUEPILL

Which STM32 Core are you using? Official STMicrolelectronics or the weird RogerClark ?
And what "Board" have you selected?

Look at the -Dxxxx arguments in a typical Build command line.

David.

Hi

It's 7inch o'clock now :slight_smile:

GxTFT is still on Roger Clark mostly, unfortunately.

Jean-Marc

@Jean-Marc,

That is a really neat way to make a BluePill backpack.

I solder BluePill and the 20x2 header onto some Protoboard. And solder individual connecting wires.

I only have 5.0 inch. What current is taken by the 7 inch backlight ?

David.

Hi David,

I can't measure right now, but the inking on the display board says 5V backlight power 400mA and 3.3V IC Power 200mA.

I think I mixed up the two 7" TFTs; the Waveshare takes less and uses only 3.3V.

Jean-Marc

Hi David,
Thank you for your quick response.

I am using maple core. It works for my blue pill with 3.5 inch LCDs (8 data bits) and i thought of using a bigger
display screen.

This message is for 7 inch LCD with blue pill...

C:\Users\johnn\OneDrive\Documents\Arduino\libraries\MCUFRIEND_kbv\utility/mcufriend_special.h:49:2: warning: #warning SSD1963 on USE_PIONSCOR_BLUEPILL [-Wcpp]
 #warning SSD1963 on USE_PIONSCOR_BLUEPILL
  ^
In file included from C:\Users\johnn\OneDrive\Documents\Arduino\libraries\MCUFRIEND_kbv\MCUFRIEND_kbv.cpp:35:0,
                 from C:\Users\johnn\OneDrive\Documents\Arduino\libraries\MCUFRIEND_kbv\OPENSMART_kbv.cpp:20:
C:\Users\johnn\OneDrive\Documents\Arduino\libraries\MCUFRIEND_kbv\utility/mcufriend_shield.h:18:2: warning: #warning WE ARE USING A SPECIAL CUSTOM DRIVER [-Wcpp]
 #warning WE ARE USING A SPECIAL CUSTOM DRIVER
  ^
In file included from C:\Users\johnn\OneDrive\Documents\Arduino\libraries\MCUFRIEND_kbv\utility/mcufriend_shield.h:16:0,
                 from C:\Users\johnn\OneDrive\Documents\Arduino\libraries\MCUFRIEND_kbv\MCUFRIEND_kbv.cpp:35,
                 from C:\Users\johnn\OneDrive\Documents\Arduino\libraries\MCUFRIEND_kbv\OPENSMART_kbv.cpp:20:
C:\Users\johnn\OneDrive\Documents\Arduino\libraries\MCUFRIEND_kbv\MCUFRIEND_kbv.cpp: In member function 'void OPENSMART_kbv::reset()':
C:\Users\johnn\OneDrive\Documents\Arduino\libraries\MCUFRIEND_kbv\utility/mcufriend_special.h:66:55: warning: left shift count >= width of type [enabled by default]
         if (pin < 8) {GP_OUT(port, CRL, 0xF<<((pin)<<2));} \
                                                       ^
C:\Users\johnn\OneDrive\Documents\Arduino\libraries\MCUFRIEND_kbv\utility/mcufriend_special.h:62:83: note: in definition of macro 'GROUP_MODE'
 #define GROUP_MODE(port, reg, mask, val)  {port->REGS(reg) = (port->REGS(reg) & ~(mask)) | ((mask)&(val)); }
                                                                                   ^
C:\Users\johnn\OneDrive\Documents\Arduino\libraries\MCUFRIEND_kbv\utility/mcufriend_special.h:66:23: note: in expansion of macro 'GP_OUT'
         if (pin < 8) {GP_OUT(port, CRL, 0xF<<((pin)<<2));} \
                       ^
C:\Users\johnn\OneDrive\Documents\Arduino\libraries\MCUFRIEND_kbv\utility/mcufriend_shield.h:1109:23: note: in expansion of macro 'PIN_OUTPUT'
 #define RESET_OUTPUT  PIN_OUTPUT(RESET_PORT, RESET_PIN)
                       ^
C:\Users\johnn\OneDrive\Documents\Arduino\libraries\MCUFRIEND_kbv\utility/mcufriend_shield.h:1118:81: note: in expansion of macro 'RESET_OUTPUT'
 #define CTL_INIT()   { GPIO_INIT(); RD_OUTPUT; WR_OUTPUT; CD_OUTPUT; CS_OUTPUT; RESET_OUTPUT; }
                                                                                 ^
C:\Users\johnn\OneDrive\Documents\Arduino\libraries\MCUFRIEND_kbv\MCUFRIEND_kbv.cpp:93:5: note: in expansion of macro 'CTL_INIT'
     CTL_INIT();
     ^
C:\Users\johnn\OneDrive\Documents\Arduino\libraries\MCUFRIEND_kbv\utility/mcufriend_special.h:66:55: warning: left shift count >= width of type [enabled by default]
         if (pin < 8) {GP_OUT(port, CRL, 0xF<<((pin)<<2));} \
                                                       ^
C:\Users\johnn\OneDrive\Documents\Arduino\libraries\MCUFRIEND_kbv\utility/mcufriend_special.h:62:94: note: in definition of macro 'GROUP_MODE'
 #define GROUP_MODE(port, reg, mask, val)  {port->REGS(reg) = (port->REGS(reg) & ~(mask)) | ((mask)&(val)); }
                                                                                              ^
C:\Users\johnn\OneDrive\Documents\Arduino\libraries\MCUFRIEND_kbv\utility/mcufriend_special.h:66:23: note: in expansion of macro 'GP_OUT'
         if (pin < 8) {GP_OUT(port, CRL, 0xF<<((pin)<<2));} \
                       ^
C:\Users\johnn\OneDrive\Documents\Arduino\libraries\MCUFRIEND_kbv\utility/mcufriend_shield.h:1109:23: note: in expansion of macro 'PIN_OUTPUT'
 #define RESET_OUTPUT  PIN_OUTPUT(RESET_PORT, RESET_PIN)
                       ^
C:\Users\johnn\OneDrive\Documents\Arduino\libraries\MCUFRIEND_kbv\utility/mcufriend_shield.h:1118:81: note: in expansion of macro 'RESET_OUTPUT'
 #define CTL_INIT()   { GPIO_INIT(); RD_OUTPUT; WR_OUTPUT; CD_OUTPUT; CS_OUTPUT; RESET_OUTPUT; }
                                                                                 ^
C:\Users\johnn\OneDrive\Documents\Arduino\libraries\MCUFRIEND_kbv\MCUFRIEND_kbv.cpp:93:5: note: in expansion of macro 'CTL_INIT'
     CTL_INIT();
     ^
In file included from C:\Users\johnn\OneDrive\Documents\Arduino\libraries\MCUFRIEND_kbv\MCUFRIEND_kbv.cpp:35:0:
C:\Users\johnn\OneDrive\Documents\Arduino\libraries\MCUFRIEND_kbv\utility/mcufriend_shield.h:808:2: warning: #warning Uno Shield on BLUEPILL [-Wcpp]
 #warning Uno Shield on BLUEPILL
  ^

I have this chunk of messages but it did compile successfully. However, the screen is still not responsive.

Hi Jean-Marc,
I have tried your GxTFT example as well but are unsure of which example to use for my case and also
any specials to include. Trying the existing examples are met with "class io" issue.
Maybe you can enlightened me on my mistakes as well.

Thank you David and Jean-Marc

It is building the SPECIAL correctly. And it is recognising the BluePill on MapleCore.

I will dig out my 5 inch SSD1963 and Backpack. And see for myself (later today)
Note that the 7 inch SSD1963 needs a different initialisation table to the 5 inch.

David.

Hi David,

Do you mean if I used a 5 inch SSD1963, it might work? Unfortunately, I only have possession of 1 unit of 7 inch SSD1963 and 1 unit of 4.3 inch (480x272) SSD1963.

Johnny.

In the CPP file:

//        table8_ads = SSD1963_480_regValues, table_size = sizeof(SSD1963_480_regValues);
        table8_ads = SSD1963_800_regValues, table_size = sizeof(SSD1963_800_regValues);
//        table8_ads = SSD1963_NHD_50_regValues, table_size = sizeof(SSD1963_NHD_50_regValues);
//        table8_ads = SSD1963_NHD_70_regValues, table_size = sizeof(SSD1963_NHD_70_regValues);
//        table8_ads = SSD1963_800NEW_regValues, table_size = sizeof(SSD1963_800NEW_regValues);
//        table8_ads = SSD1963_800ALT_regValues, table_size = sizeof(SSD1963_800ALT_regValues);
        p16 = (int16_t *) & HEIGHT;
        *p16 = 480;
        p16 = (int16_t *) & WIDTH;
        *p16 = 800;
        break;

It defaults to SSD1963_800_regValues for 5 inch.
You would change to SSD1963_NHD_70_regValues for 7 inch. i.e. enable / disable the //
Or SSD1963_480_regValues for 480x272 (and change the width and height values)

@johnny_wee, Hi Johnny,

I had noticed the coincidence of two topics concerning two 7" displays with each one having the same controller as each of my two 7" displays. And your topic about using a BluePill with your display, like I did.

I didn't intend to promote GxTFT for your case, as most likely your wiring is different; I didn't check.

You are better served with an existing or a new special from David, and his support.

I have tried your GxTFT example as well but are unsure of which example to use for my case and also
any specials to include. Trying the existing examples are met with "class io" issue.
Maybe you can enlightened me on my mistakes as well.

I try to explain in few words anyway what you would need to do to use GxTFT with your configuration.

First you would check if there is an example that matches your configuration, by looking at the names of the examples. There isn't. The closest would be for Arduino Due.

Then you would take a look at the general example GxTFT_graphicstest.ino.
In this example you could uncomment lines to select controller and io class includes, controller and io class instances (constructors), and display instance. Or further down you can select (uncomment) an include for a preconfigured configuration for one of my TFTs, if it matches.
Oops, unfortunately there isn't one, although I used this configuration. I seem to have been lazy.
So you can't look up which IO class I used. It can only be the GxIO_STM32F103BluePill_P16.

You would then compare the wiring supported by GxIO_STM32F103BluePill_P16 with your wiring, and either adapt it or create a new class. This class uses bit-shuffling in a similar way as the "specials" of David. The main difference is that I use a separate class for each wiring. And I create only wiring classes for displays that I have.

It can be done, but with the help of David his "specials" are easier to use.

Jean-Marc

David,
Tried

//        table8_ads = SSD1963_480_regValues, table_size = sizeof(SSD1963_480_regValues);
//        table8_ads = SSD1963_800_regValues, table_size = sizeof(SSD1963_800_regValues);
//        table8_ads = SSD1963_NHD_50_regValues, table_size = sizeof(SSD1963_NHD_50_regValues);
      table8_ads = SSD1963_NHD_70_regValues, table_size = sizeof(SSD1963_NHD_70_regValues);
//        table8_ads = SSD1963_800NEW_regValues, table_size = sizeof(SSD1963_800NEW_regValues);
//       table8_ads = SSD1963_800ALT_regValues, table_size = sizeof(SSD1963_800ALT_regValues);
        p16 = (int16_t *) & HEIGHT;
        *p16 = 480;
        p16 = (int16_t *) & WIDTH;
        *p16 = 800;
        break;

and some others in the list. Same results.
Force tft.begin(0x1963) too. My wiring of

LCD : D0 ... D15
BluePill : B0,B1,A15,B3,B4,....,B15

LCD : RD, WR , RS , CS , RESET
Bluepill : A0 A1 A2 A3 A4/A8

Tried A4 and A8 but same results.

@Jean-Marc
Thanks for the explanation and advise

Tried what you have mentioned with Graphictest and uncommenting suitable headers days ago before i posted for help.

Johnny

@johnny_wee,

You must be joking. Do you really expect such a ratsnest of Dupont wires to work ?

I have built with proper ST Core. And am able to use up to date Adafruit GFX files e.g. v1.9.0
If I build with the weird RogerClark Core I have to downgrade to Adafruit_GFX v1.7.5

The compatability is nothing to do with MCUFRIEND_kbv. It is because Adafruit has added dependencies that are not relevant to most third party libraries like MCUFRIEND_kbv.

Anyway, since I don't know where you got your PIONSCORE special:

// #################################### STM32 PIONSCOR #######################################
#elif defined(USE_PIONSCOR_BLUEPILL) && (defined(__STM32F1__) || defined(ARDUINO_BLUEPILL_F103CB)) // MAPLECORE or STM32CORE 
//LCD Pins : | D15| D14| D13| D12| D11| D10| D9| D8| D7| D6| D5| D4| D3|  D2| D1| D0|
//BLUE PILL: |PB15|PB14|PB13|PB12|PB11|PB10|PB9|PB8|PB7|PB6|PB5|PB4|PB3|PA15|PB1|PB0|
//LCD Pins : |RD  |WR  |RS  |CS  |RST |
//BLUE PILL: |PA0 |PA1 |PA2 |PA3 |PA8 |

#warning SSD1963 on USE_PIONSCOR_BLUEPILL
#define USES_16BIT_BUS

#if defined(__STM32F1__)   //weird Maple Core
#define REGS(x) regs->x
#else                      //regular ST Core
#define REGS(x) x
#define GPIO_INIT()   { RCC->APB2ENR |= RCC_APB2ENR_IOPAEN | RCC_APB2ENR_IOPBEN | RCC_APB2ENR_IOPCEN | RCC_APB2ENR_IOPDEN | RCC_APB2ENR_AFIOEN; \
        AFIO->MAPR |= AFIO_MAPR_SWJ_CFG_1;}
#endif

#define WRITE_DELAY { }
#define READ_DELAY  { RD_ACTIVE; }
//
#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 PIN_OUTPUT(port, pin) {\
        if (pin < 8) {GP_OUT(port, CRL, 0xF<<((pin)<<2));} \
        else {GP_OUT(port, CRH, 0xF<<((pin&7)<<2));} \
    }
#define PIN_INPUT(port, pin) { \
        if (pin < 8) { GP_INP(port, CRL, 0xF<<((pin)<<2)); } \
        else { GP_INP(port, CRH, 0xF<<((pin&7)<<2)); } \
    }

#define PIN_HIGH(port, pin)   (port)-> REGS(BSRR) = (1<<(pin))
#define PIN_LOW(port, pin)    (port)-> REGS(BSRR) = (1<<((pin)+16))

#define RD_PORT GPIOA
#define RD_PIN  0
#define WR_PORT GPIOA
#define WR_PIN  1
#define CD_PORT GPIOA
#define CD_PIN  2
#define CS_PORT GPIOA
#define CS_PIN  3
#define RESET_PORT GPIOA
#define RESET_PIN  8

// configure macros for the data pins DB2 on PA15.  All others on PB0-1, PB3-15
#define BMASK 0xFFFB
#define write_16(d) { \
        GPIOA->REGS(BSRR) = (1<<15) << 16; \
        GPIOB->REGS(BSRR) = (BMASK) << 16; \
        GPIOA->REGS(BSRR) = ((d) & (1<<2)) << 13; \
        GPIOB->REGS(BSRR) = (d) & BMASK; \
    }

#define read_16()     ( ((GPIOA->REGS(IDR) & (1<<15)) >> 13) | (GPIOB->REGS(IDR) & BMASK) )

//                                              PA15                        PB15-PB8                 PB7-PB3,PB1-PB0
#define setWriteDir() {GP_OUT(GPIOA, CRH, 0xF0000000); GP_OUT(GPIOB, CRH, 0xFFFFFFFF); GP_OUT(GPIOB, CRL, 0xFFFFF0FF); }
#define setReadDir()  {GP_INP(GPIOA, CRH, 0xF0000000); GP_INP(GPIOB, CRH, 0xFFFFFFFF); GP_INP(GPIOB, CRL, 0xFFFFF0FF); }

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

The RogerClark Core is a nightmare. Why don't you use the official Core from STMicroelectronics ?
ST are the actual manufacturers of the STM32 chips. ST support the official ST Core

David.

David,

I obtained the Pionscor special from your reply to Pionscor quite sometime back.

You are right that Rogerclark core works for my bluepill with 3.5" lcd only for version of Adafruit_GFX_v1.7.5 or lower.
I am still using this core for and Adafruit_GFX version for this 7" lcd which seems to have some issues.

Will use proper ST core and latest Adafruit_GFX version tomorrow.

Ribbon cable used instead of the Dupont cable which I find it too filmsy too. Ribbon cable works for my Mega with this 7" LCD.

20200807_202746 (2).jpg

I am horrified by your ribbon cables and by your Dupont cables. (and the un-removed plastic film)

Look at Jean-Marc's photos in #2
Or read how I made a backpack.

BluePills are so cheap that you should use them as one-off component.
e.g. Jean-Marc has soldered the 20x2 long-pin header directly to the BluePill.

David.

David,

Great news, it works.

It would not be possible without you.

Thank you so much for your guidance.

Have a great day.

Johnny

Your colours are wrong for the drawRect() test. And you need to unpeel the horrible plastic film.

Please run all the library examples. You might need to put a while (!Serial) ; with a timeout for the RogerClark USB Serial to start.

Please let me know about any problems. Especially colours, rotations, best init table sequences.

I suggest that you copy Jean-Marc's backpack. Ask if you want different wiring.

David.

David, Johnny,

please note that my wiring requires more shift operations, and thus is slower.
Johnny could use A2 instead of A15, thus avoid any shift operations.
And he could use direct write to PORTB, as writing B2 doesn't hurt.

Does anybody know why B2 is omitted as pin on BluePill?
It is a boot mode pin, but could still be used as an output pin.
Same story with a different Bx pin on STM32F411 BlackPill.

Jean-Marc

Shifts should be avoided on an AVR.
Shifts are not expensive on an ARM because it has a barrel roller.

In an ideal world you would have a single 16-bit PORT.
Or contiguous bits on a single 32-bit PORT.

The PIONSCOR data bus involves two PORTs. And is pretty quick.
There are plenty of two PORT opportunities.

Yes, random pins on multiple ports get untidy e.g. Uno shields on Mega, Leo, Zero, Due, Nucleo, ...
But a Uno shield on a Uno works ok.

David.

David

I can live with the pin configuration. Building a backpack will be fine with me.
Since you mentioned, I realised that the rotation routine did not execute.
I will keep you posted on the findings after run more tests.

Jean-Marc
Your piggyback board is neat and tidy. Nice job.

Johnny

David

I have tried different settings from

//        table8_ads = SSD1963_480_regValues, table_size = sizeof(SSD1963_480_regValues);
     table8_ads = SSD1963_800_regValues, table_size = sizeof(SSD1963_800_regValues);
//        table8_ads = SSD1963_NHD_50_regValues, table_size = sizeof(SSD1963_NHD_50_regValues);
//       table8_ads = SSD1963_NHD_70_regValues, table_size = sizeof(SSD1963_NHD_70_regValues);
//        table8_ads = SSD1963_800NEW_regValues, table_size = sizeof(SSD1963_800NEW_regValues);
//      table8_ads = SSD1963_800ALT_regValues, table_size = sizeof(SSD1963_800ALT_regValues);

NHD-50 and NHD-70 gives me black screen while the others did not complete the full display routine.

800 and 800NEW
and

What other changes do I need? Thanks

Johnny