You are here

Own type of LCD with emWin library? | Cypress Semiconductor

Own type of LCD with emWin library?

Summary: 12 Replies, Latest post by majed on 25 Jul 2014 02:22 PM PDT
Verified Answers: 0
Last post
Log in to post new comments.
user_78878863's picture
2551 posts

I'm currently looking at the documenation for the new emWin support. First of all, in the PSoC5 folder, there is no display driver (in the PSoC3 folder, there is the LCD667CC.c). Is this missing?

Also, I'm using a display which doesn't seem to be supported neither the Graphic LCD Interface component, nor the PSoC3 emWin code (provided I could copy it over to the PSoC5) - it's a SED1335-controlled display. From a hardware perspective, it looks like it should work with the PSoC component (because it works the same way), but the documentation is silent about that.

The emWin library documentation is also silent about interfacing other. (The real emWin manual shows a list of driver, where my display is included, and also show a template driver).

My questions:

  • is the Graphic LCD interface component supposed / expected to work with other controllers?
  • What is the supposed way of interfacing own LCDs (what is the supported LCD, actually?)
  • How can I get my hands at the template driver?




rtcy's picture
Cypress Employee
112 posts


did you ever have a chance to check out the emwin documentation on the Segger website?

You might want to download the User Manual for emWin. It is a large document but you want to focus on chapter 29 "Display Drivers" to get answers to your question.



user_22393527's picture
65 posts

 I have the exact same question, and it is not clear to me what the answer is. I have read the component datasheet pdf about 3 times now.

as one of the steps it says to:

 "Add a component to communicate with a graphics LCD panel to your project. The

emWinGraphics library is a software library. The communication to the panel is done using

the appropriate hardware component for the panel. The Cypress component library includes

two components that interface to an LCD panel: Graphics LCD Interface or Graphics LCD


Am I incorrect in reading this as one of ther components has to be used in order to use the emWin library? I have SPI graphics panel selected for my desing (i don't need color, and SPI is easy to wire up) . I would be happy to have the emWin write to an internal frame buffer and perhaps have DMA do all the transfering out over SPI to the LCD. Can that be done? It seems "memory devices" of emWin is supported on PSOC 5 so it sounds like a frame buffer is doable.



user_22393527's picture
65 posts

 Looks like I am digging up stale threads lately, but I have started looking into this so I thought I would post what I found. Might be helpful to others, but its also a way to not loose my notes on the matter.

The emWin software driver calls the PSoC graphics components via some macros -- they can be found in the .h header file for the graphics LCD components once it is generated. They look like this, where INSTANCE is the name of your component for the parallel interface component psoc5:

#define CYGRAPHICS_START()                  INSTANCE_Start()

#define CYGRAPHICS_STOP()                   INSTANCE_Stop()

#define CYGRAPHICS_WRITE(addr, data)        INSTANCE_Write8(addr, data)

#define CYGRAPHICS_READ(addr)               INSTANCE_Read8(addr)

#define CYGRAPHICS_WRITEM(addr, data, num)  INSTANCE_WriteM8(addr, data, num)

they are slighly different for the other graphics component that implements the controller in the PSoC

The CYGRAPHICS routines are called from LCDConf.c. I think, though I have not yet been successful, that these routines can be adapted to use other controllers. For instance, I have a SPI connected module, and I am able to write to the display because I substituded the SPI routines for the graphics writes, though to be honest, its total garbage being displayed at the moment. I took a slightly different approach and enabled 3-wire serial in the compact color driver (as discussed in the emWin documentation). It is necessary to note that some features cannot be used with 3 wire because emWin requires read and write access to the display memory (sprites, nors, etc). 

I am toying with the idea of allocating a frame buffer in psoc ram that emWin will believe is the graphics ram, and work on that. This buffer can then be transmitted separately, perhaps with DMA setoff by a timer. Obvioulsy it would take a lot of ram, but a monochrome panel can maybe be bit packed, and if my math is correct, an 8bpp 126x64 OLED can be contained in 8192 bytes.

user_22393527's picture
65 posts

 I detoured the CYGRAPHICS_WRITE() calls to save a value to a RAM array. I used the controller-less graphics component (in other words, the GUIDRV_Control.c file) The ram array is a linear thing arranged exactly like the vRAM in the display I am using, where each pixel is 4 bits, and increase starting in the top left  of the display to the right and then down. This ram array gave me the most grief, as I can't work out an easy way to write specific nibbles. In any case, I can dump this entire frame buffer over SPI (at 15 MHz) to the 128x64x4bpp display in about 10 milliseconds. (assuming I am reading the logic analyzer corrrectly). I don't think screen refresh is much of an issue, the actual drawing of items is probably more time consuming. 

Anyone have any good ideas on how to write nibbles?

user_460349's picture
1362 posts

How about this.

#define HIGH_NIBBLE_MASK (0xF0)
#define LOW_NIBBLE_MASK (0xF)

extern uchar RAM1_2; /* b0-b3 is for 1 pixel and b4-b7 for another pixel;*/

/* To write the lower nibble */

newData &= LOW_NIBBLE_MASK;  /* new data bit0-3 is the data */
RAM1_2 |= newData;

/* To write the upper nibble */

/* new data bit4-7 is the data, use newData =<< 4 if it is the lower e bits */


RAM1_2 |= newData;


user_22393527's picture
65 posts


ended up using it like this because the LCD needed pixel 0 and 1 mapped to high and low nibble of the first byte:

#define COLUMN_NO   128 //VXSIZE_PHYS  

#define ROW_NO 64 //VYSIZE_PHYS

#define PIXELS COLUMN_NO/2 * ROW_NO //the product should be the bytes needed to hold the entire vram

static uint8 vRAM[PIXELS]; //array the size of the VRAM on the display


#define HIGH_NIBBLE_MASK (0xF0) //0b11110000

#define LOW_NIBBLE_MASK (0x0F) //0b00001111


void FrameBuffer_Write(uint16 addr, uint8 dat)


// if the x pixel is even we want the high nibble of the index byte set otherwise set the low nibble

if (addr%2 == 0) {

vRAM[(addr)/2] = (vRAM[(addr)/2] & HIGH_NIBBLE_MASK )| dat ;


else  {

vRAM[(addr)/2] = (vRAM[(addr)/2] & LOW_NIBBLE_MASK )| (dat << 4) ;



user_22393527's picture
65 posts

 I forgot to mention:

#define CYGRAPHICS_WRITE(addr, data)        FrameBuffer_Write(addr, data)

user_460349's picture
1362 posts

 Looks good.

at the beginning of the function I would mask off the top 4 bit first


dat &= LOW_NIBBLE_MASK; /* make sure top 4 bits are 0*/


As my habbit due to limitation of older generation of compilers,

I would use 


"X & 1" instead of X%2


Because division takes longer time and more code (assembly code).

New compilers may do this automatically. 

user_1377889's picture
9249 posts

Do not think I am paranoid at all, but to look at code with your "% 2" or "& 1" after half a year has passed will make you think what you have wanted to express 6 months ago. Just to increase readability I would have written


#define odd(x) (x & 0x01)

#define even(x) (!odd(x))


Now your statement can be changed to a more readable

if (addr%2 == 0)


if (even(addr))

which now expresses literally what the reason for different paths is. No comment needed. I like that!


Happy coding


user_460349's picture
1362 posts

 Good idea. 

Log in to post new comments.