Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
KeithS_76
Employee
Employee
10 replies posted First question asked 5 sign-ins

I am trying to use CY8CKIT-028-TFT to display a moving image.  I took a graphical Hello World example (well, technically "I feel good!", not "Hello world!") from ModusToolbox 101 chapter 2, and I have used it and a basic understanding of the emWin interface to get animation working.

My problem is that everything I draw is sent to the screen immediately, showing all the intermediate steps, which is both inefficient and distracting to watch.  Is there a way (either in hardware on the TFT, or in software in the emWin library) to cache/buffer draws so that things only get sent to the TFT screen when one frame worth of drawing is done?  Or is a client that wants to move a square responsible for erasing the trailing edge and drawing the leading edge if it wants to minimize flickering?

0 Likes
1 Solution
Bhamy
Moderator
Moderator
Moderator
100 replies posted 10 likes given 10 likes received

Hi @KeithS_76 ,

This issue is mostly because of the low frame rate of the display interface. There are several ways to fix this issue. Below is my explanation to improve the performance.

PSOC 6 dose not have a dedicated interface to connect TFT display. But display can be interfaced to using the GPIO bit banging method and sometimes also using TCPWM. CY8CKIT-028-TFT has 240x320 resolution TFT panel interfaced to any microcontroller using parallel interface. The display pins are routed to the Arduino compatible header as marked in green in the Figure 1.

 

Bhamy_0-1691659893632.png

 

Figure 1 CY8CKIT-028-TFT Arduino header pinout

Some of the PSOC 6 evaluation kits are designed in such a way that the shield can be plugged in directly to the EVK and the display can be driven by implementing the driving functionality in software. CY8CKIT-062-WiFi-BT has  the Arduino compatible header  can be connected to the TFT shield as shown in the Figure 2 and pins connection is as shown in the Table 1

Table 1 CY8CKIT-028-TFT and CY8CKIT-062-WiFi-BT display connection details

 

CY8CKIT-028-TFT

CY8CKIT-062-WiFi-BT

Reset

TFT_DISP_RST_L

P12_2

Data/Command

TFT_DISP_D/C

P12_1

Write enable

TFT_DISP_WR_L

P12_0

Read enable

TFT_DISP_RD_L

P12_3

Data 15

TFT_DISP_DB15

P13_1

Data 14

TFT_DISP_DB14

P13_0

Data 13

TFT_DISP_DB13

P0_2

Data 12

TFT_DISP_DB12

P9_5

Data 11

TFT_DISP_DB11

P9_4

Data 10

TFT_DISP_DB10

P9_2

Data 9

TFT_DISP_DB9

P9_1

Data 8

TFT_DISP_DB8

P9_0

 

 

Bhamy_1-1691659893640.png

 

Figure 2 CY8CKIT-062-WiFi-BT Arduino header pinout

Display driver (display-tft-st7789v) available in Infineon Github needs to be included in the project along with the graphic libraries like emWin to drive the display.

The current display write function (A) implementation is shown below code snippet:

static inline void write_data(uint8_t data)
{
    cyhal_gpio_write(pins->db08,  data     & 0x01);
    cyhal_gpio_write(pins->db09, (data>>1) & 0x01);
    cyhal_gpio_write(pins->db10, (data>>2) & 0x01);
    cyhal_gpio_write(pins->db11, (data>>3) & 0x01);
    cyhal_gpio_write(pins->db12, (data>>4) & 0x01);
    cyhal_gpio_write(pins->db13, (data>>5) & 0x01);
    cyhal_gpio_write(pins->db14, (data>>6) & 0x01);
    cyhal_gpio_write(pins->db15, (data>>7) & 0x01);
    cyhal_gpio_write(pins->nwr, 0u);
    cyhal_gpio_write(pins->nwr, 1u);
}

 

Each bit from the data is shifted in respective position and the bit value is set to the data (GPIO) pin. This implementation will work but it effects the performance very badly.

To improve the performance, the data needs to be written to the respective GPIO port register (B).

#define PORT9_MSK_1              0x07
#define PORT9_MSK_2              0x18
#define PORT9_MSK_2_SHIFT        1
#define PORT0_MSK_1              0x20
#define PORT0_MSK_1_SHIFT        3
#define PORT13_MSK_1             0xC0
#define PORT13_MSK_1_SHIFT       6

static inline void write_data(uint8_t data)
{
       GPIO_PRT9->OUT = ((data & PORT9_MSK_2)<<PORT9_MSK_2_SHIFT)
| (data & PORT9_MSK_1);
       GPIO_PRT0->OUT = ((data & PORT0_MSK_1)>>PORT0_MSK_1_SHIFT);
       GPIO_PRT13->OUT = ((data & PORT13_MSK_1)>>PORT13_MSK_1_SHIFT);   
       GPIO_PORT_12->OUT_SET = 0x01;
       GPIO_PORT_12->OUT_CLR = 0x01;
}

 

With the above implementation the display performance is better than before.

There is still further option to improve the performance by changing the Hardware routing. Table 2 shows the hardware changes needed to further improve the display performance.

 Table 2 Optimized hardware connection for display

 

CY8CKIT-028-TFT

CY8CKIT-062-WiFi-BT

Reset

TFT_DISP_RST_L

P12_2

Data/Command

TFT_DISP_D/C

P12_1

Write enable

TFT_DISP_WR_L

P12_0

Read enable

TFT_DISP_RD_L

P12_3

Data 15

TFT_DISP_DB15

P9_7

Data 14

TFT_DISP_DB14

P9_6

Data 13

TFT_DISP_DB13

P9_5

Data 12

TFT_DISP_DB12

P9_4

Data 11

TFT_DISP_DB11

J2_P9_3

Data 10

TFT_DISP_DB10

P9_2

Data 9

TFT_DISP_DB9

P9_1

Data 8

TFT_DISP_DB8

P9_0

 

With this hardware changes the driver (C) will be simplified and is as shown below:

static inline void write_data(uint8_t data)
{
    GPIO_PRT9->OUT = data;
    GPIO_PORT_12->OUT_SET = 0x01;
    GPIO_PORT_12->OUT_CLR = 0x01;
}

 

With these changes, 48.95 Hz display Frame rate is achieved.

Optionally the function call and be eliminated by adding the write_data functionality inside the for loop. Further to reduce the for loop overhead driver (D) can be further optimized by reducing the number of checks due to the for loop as shown in the below code snippet:

    for (i = 0; i < num; i+=4)
    {
       GPIO_PRT9->OUT = data[i];
       GPIO_PRT12->OUT_CLR = 1;
       GPIO_PRT12->OUT_SET = 1;

       GPIO_PRT9->OUT = data[i+1];
       GPIO_PRT12->OUT_CLR = 1;
       GPIO_PRT12->OUT_SET = 1;

       GPIO_PRT9->OUT = data[i+2];
       GPIO_PRT12->OUT_CLR = 1;
       GPIO_PRT12->OUT_SET = 1;

       GPIO_PRT9->OUT = data[i+3];
       GPIO_PRT12->OUT_CLR = 1;
       GPIO_PRT12->OUT_SET = 1;  
    }

This will further boost the display framerate to 54.36 Hz.

Result:

Method

WR pin frequency

FPS

A (Shift and write)

422 KHz

2.74

B (Direct register write)

4.18 MHz

27.2

C (Hardware change)

7.52 MHz

48.95

D (For loop expand)

8.35 MHz

54.36

 

Kindly let me know if the above explanation helps your implementation. Let me know if you have any further issues on it.

Best regards

Bhamy Narasimha Shenoy 

View solution in original post

0 Likes
6 Replies
Bhamy
Moderator
Moderator
Moderator
100 replies posted 10 likes given 10 likes received

Hi @KeithS_76 ,

This issue is mostly because of the low frame rate of the display interface. There are several ways to fix this issue. Below is my explanation to improve the performance.

PSOC 6 dose not have a dedicated interface to connect TFT display. But display can be interfaced to using the GPIO bit banging method and sometimes also using TCPWM. CY8CKIT-028-TFT has 240x320 resolution TFT panel interfaced to any microcontroller using parallel interface. The display pins are routed to the Arduino compatible header as marked in green in the Figure 1.

 

Bhamy_0-1691659893632.png

 

Figure 1 CY8CKIT-028-TFT Arduino header pinout

Some of the PSOC 6 evaluation kits are designed in such a way that the shield can be plugged in directly to the EVK and the display can be driven by implementing the driving functionality in software. CY8CKIT-062-WiFi-BT has  the Arduino compatible header  can be connected to the TFT shield as shown in the Figure 2 and pins connection is as shown in the Table 1

Table 1 CY8CKIT-028-TFT and CY8CKIT-062-WiFi-BT display connection details

 

CY8CKIT-028-TFT

CY8CKIT-062-WiFi-BT

Reset

TFT_DISP_RST_L

P12_2

Data/Command

TFT_DISP_D/C

P12_1

Write enable

TFT_DISP_WR_L

P12_0

Read enable

TFT_DISP_RD_L

P12_3

Data 15

TFT_DISP_DB15

P13_1

Data 14

TFT_DISP_DB14

P13_0

Data 13

TFT_DISP_DB13

P0_2

Data 12

TFT_DISP_DB12

P9_5

Data 11

TFT_DISP_DB11

P9_4

Data 10

TFT_DISP_DB10

P9_2

Data 9

TFT_DISP_DB9

P9_1

Data 8

TFT_DISP_DB8

P9_0

 

 

Bhamy_1-1691659893640.png

 

Figure 2 CY8CKIT-062-WiFi-BT Arduino header pinout

Display driver (display-tft-st7789v) available in Infineon Github needs to be included in the project along with the graphic libraries like emWin to drive the display.

The current display write function (A) implementation is shown below code snippet:

static inline void write_data(uint8_t data)
{
    cyhal_gpio_write(pins->db08,  data     & 0x01);
    cyhal_gpio_write(pins->db09, (data>>1) & 0x01);
    cyhal_gpio_write(pins->db10, (data>>2) & 0x01);
    cyhal_gpio_write(pins->db11, (data>>3) & 0x01);
    cyhal_gpio_write(pins->db12, (data>>4) & 0x01);
    cyhal_gpio_write(pins->db13, (data>>5) & 0x01);
    cyhal_gpio_write(pins->db14, (data>>6) & 0x01);
    cyhal_gpio_write(pins->db15, (data>>7) & 0x01);
    cyhal_gpio_write(pins->nwr, 0u);
    cyhal_gpio_write(pins->nwr, 1u);
}

 

Each bit from the data is shifted in respective position and the bit value is set to the data (GPIO) pin. This implementation will work but it effects the performance very badly.

To improve the performance, the data needs to be written to the respective GPIO port register (B).

#define PORT9_MSK_1              0x07
#define PORT9_MSK_2              0x18
#define PORT9_MSK_2_SHIFT        1
#define PORT0_MSK_1              0x20
#define PORT0_MSK_1_SHIFT        3
#define PORT13_MSK_1             0xC0
#define PORT13_MSK_1_SHIFT       6

static inline void write_data(uint8_t data)
{
       GPIO_PRT9->OUT = ((data & PORT9_MSK_2)<<PORT9_MSK_2_SHIFT)
| (data & PORT9_MSK_1);
       GPIO_PRT0->OUT = ((data & PORT0_MSK_1)>>PORT0_MSK_1_SHIFT);
       GPIO_PRT13->OUT = ((data & PORT13_MSK_1)>>PORT13_MSK_1_SHIFT);   
       GPIO_PORT_12->OUT_SET = 0x01;
       GPIO_PORT_12->OUT_CLR = 0x01;
}

 

With the above implementation the display performance is better than before.

There is still further option to improve the performance by changing the Hardware routing. Table 2 shows the hardware changes needed to further improve the display performance.

 Table 2 Optimized hardware connection for display

 

CY8CKIT-028-TFT

CY8CKIT-062-WiFi-BT

Reset

TFT_DISP_RST_L

P12_2

Data/Command

TFT_DISP_D/C

P12_1

Write enable

TFT_DISP_WR_L

P12_0

Read enable

TFT_DISP_RD_L

P12_3

Data 15

TFT_DISP_DB15

P9_7

Data 14

TFT_DISP_DB14

P9_6

Data 13

TFT_DISP_DB13

P9_5

Data 12

TFT_DISP_DB12

P9_4

Data 11

TFT_DISP_DB11

J2_P9_3

Data 10

TFT_DISP_DB10

P9_2

Data 9

TFT_DISP_DB9

P9_1

Data 8

TFT_DISP_DB8

P9_0

 

With this hardware changes the driver (C) will be simplified and is as shown below:

static inline void write_data(uint8_t data)
{
    GPIO_PRT9->OUT = data;
    GPIO_PORT_12->OUT_SET = 0x01;
    GPIO_PORT_12->OUT_CLR = 0x01;
}

 

With these changes, 48.95 Hz display Frame rate is achieved.

Optionally the function call and be eliminated by adding the write_data functionality inside the for loop. Further to reduce the for loop overhead driver (D) can be further optimized by reducing the number of checks due to the for loop as shown in the below code snippet:

    for (i = 0; i < num; i+=4)
    {
       GPIO_PRT9->OUT = data[i];
       GPIO_PRT12->OUT_CLR = 1;
       GPIO_PRT12->OUT_SET = 1;

       GPIO_PRT9->OUT = data[i+1];
       GPIO_PRT12->OUT_CLR = 1;
       GPIO_PRT12->OUT_SET = 1;

       GPIO_PRT9->OUT = data[i+2];
       GPIO_PRT12->OUT_CLR = 1;
       GPIO_PRT12->OUT_SET = 1;

       GPIO_PRT9->OUT = data[i+3];
       GPIO_PRT12->OUT_CLR = 1;
       GPIO_PRT12->OUT_SET = 1;  
    }

This will further boost the display framerate to 54.36 Hz.

Result:

Method

WR pin frequency

FPS

A (Shift and write)

422 KHz

2.74

B (Direct register write)

4.18 MHz

27.2

C (Hardware change)

7.52 MHz

48.95

D (For loop expand)

8.35 MHz

54.36

 

Kindly let me know if the above explanation helps your implementation. Let me know if you have any further issues on it.

Best regards

Bhamy Narasimha Shenoy 

0 Likes
KeithS_76
Employee
Employee
10 replies posted First question asked 5 sign-ins

The direct register write dramatically improved throughput to the TFT, thank you.  I can still occasionally see flickering if the TFT redraws at the exact wrong time, though.  Is there any way to eliminate that, instead of merely making it much less likely?

Also, why is the direct register write not the default implementation in the display-tft-st7789v library?

0 Likes
Bhamy
Moderator
Moderator
Moderator
100 replies posted 10 likes given 10 likes received

Hi @KeithS_76 ,

Flickering issue:

This could be application specific issue. Can you please share your project or video of the observation?

Driver implementation changes:

The current driver implementation is a general driver which will be used with several devices. The pin mapping will be different for each devices. Thus to simplify the pin mapping issue the general bit banging with shifting bits was implemented.

Kindly let me know if you have any further questions on this topic.

Best regards

Bhamy Narasimha Shenoy 

0 Likes
Bhamy
Moderator
Moderator
Moderator
100 replies posted 10 likes given 10 likes received

Hi @KeithS_76 ,

Did you get some chance to review my previous response?

Best regards

Bhamy Narasimha Shenoy

0 Likes
Bhamy
Moderator
Moderator
Moderator
100 replies posted 10 likes given 10 likes received

Hi @KeithS_76 ,

Just following up to know if you got some chance to review the my responses. Let me know if you need any further support with it.

Best regards

Bhamy Narasimha Shenoy

0 Likes
Bhamy
Moderator
Moderator
Moderator
100 replies posted 10 likes given 10 likes received

Hi @KeithS_76 ,

This thread will be locked due to inactivity. Feel free to create new thread when you have any further issues with this topic.

Best regards

Bhamy Narasimha Shenoy

0 Likes