Jump to content

Get ST7565 running


Mad River

Recommended Posts

Hi,

 

I just ported the ThreadX OS and I would like to draw something in a display which have a ST7565 controller.

I did the following:

1. Created the board_ST7565.h file (attached)

2. Set #define GFX_USE_GDISP  TRUE

3. Added the following code to test:

    coord_t     width, height;

    // Initialize and clear the display
    gfxInit();

    // Get the screen size
    width = gdispGetWidth();
    height = gdispGetHeight();

 

After running that, width = 30089 and height = 0.

I am sure I am missing some things.

Where do I tell the uGFX that I am using a ST7565?

Which other steps must be made in order to do a simple draw test?

Is there a tutorial?

 

board_ST7565.h

Link to comment
Share on other sites

Well, I did some more configurations, but it still doesn't work.

#define GFX_USE_GDISP  TRUE

#define GDISP_TOTAL_DISPLAYS                         1

#define GDISP_DRIVER_LIST                            GDISPVMT_ST7565
    #ifdef GDISP_DRIVER_LIST
//        // For code and speed optimization define as TRUE or FALSE if all controllers have the same capability
//        #define GDISP_HARDWARE_STREAM_WRITE          FALSE
//        #define GDISP_HARDWARE_STREAM_READ           FALSE
//        #define GDISP_HARDWARE_STREAM_POS            FALSE
//        #define GDISP_HARDWARE_DRAWPIXEL             FALSE
//        #define GDISP_HARDWARE_CLEARS                FALSE
//        #define GDISP_HARDWARE_FILLS                 FALSE
//        #define GDISP_HARDWARE_BITFILLS              FALSE
//        #define GDISP_HARDWARE_SCROLL                FALSE
//        #define GDISP_HARDWARE_PIXELREAD             FALSE
//        #define GDISP_HARDWARE_CONTROL               FALSE
//        #define GDISP_HARDWARE_QUERY                 FALSE
//        #define GDISP_HARDWARE_CLIP                  FALSE

        #define GDISP_PIXELFORMAT                    GDISP_PIXELFORMAT_RGB888
    #endif

 

Edited by Mad River
Link to comment
Share on other sites

After set the #defines mentioned above, I started getting these errors:

multiple_definition_error.JPG.e27d3ff385936dc40d5cb156b8c55966.JPG

 

I already made a full search, and these functions are not defined anywhere else the gdisp.c file.

What may causing this problem?

 

 

EDIT:

I removed the gdisp.c from the build path and the multiple definition problem ended.

But the code still doesn't work.

Edited by Mad River
Link to comment
Share on other sites

Removing gdisp.c from the build path did not work.

So I inserted it back. And inserted gdriver.c and other missing files as well.

Now, the files which are being compiled are these:

error.thumb.JPG.04ce6611388f949b0f8b9ddeb166e9ad.JPG

The include path:

include_path.JPG.d706bcbdcee1edd799ff8c5aa0dd8d14.JPG

 

I REALLY don't know what to do anymore.

I never have that much problems to get a library running...

 

From one stackoverflow.com thread found this:

"You are getting multiple definition errors because you are including your .c files in your .c files. It's the linker's job to make sure they come together. Good practice is to only include .h files in your .cfiles, and make sure the .h files don't include function definitions (only function prototypes).

By #includeing your .c files, you are defining the functions at least twice: once when FIFO.c is compiled, and again when main.c (which #includes FIFO.c, copying it verbatim into the text before compilation) is compiled. When it comes to link time, the linker sees e.g. queue_new() defined in both FIFO.o and main.o and barfs on the multiple definition of all the functions in FIFO.c."

 

I suppose I am having these problem because of the "#include "gdisp.c" (same logic to the other files) inside the makefiles, but I don't know how to avoid it.

Edited by Mad River
Link to comment
Share on other sites

Well,

I removed all .c or .mk files from the build path.

The ONLY one left is the gfx_mk.c.

Now it compiles.

Run the same code:

    // Initialize and clear the display
    gfxInit();

    // Get the screen size
    width = gdispGetWidth();
    height = gdispGetHeight();

 

Result:

width = 31413

heigth = 0

Link to comment
Share on other sites

Revert your project back to the state where everything was compiling without any modules enabled (just GOS which is always enabled) and then follow the guide on Keil µVision that has been linked previously that explains step-by-step how to use the single-file-inclusion mechanism. It explains and shows how to add a driver: https://wiki.ugfx.io/index.php/Using_Keil_µVision_5_MDK-ARM#Adding_Drivers
The process is exactly the same on Eclipse. The single file inclusion mechanism is universal.

Our community member and IDE expert @cpu20 is currently in the process of writing an official & very detailed guide on how to add the µGFX library to an existing eclipse project. I'm sure he could help you out here already if you have problems doing just what the guide linked above explains and demonstrates.

In general: Just don't add any files you're not explicitly being told to add.

Link to comment
Share on other sites

8 hours ago, Joel Bodenmann said:

Our community member and IDE expert @cpu20 is currently in the process of writing an official & very detailed guide on how to add the µGFX library to an existing eclipse project. I'm sure he could help you out here already if you have problems doing just what the guide linked above explains and demonstrates.

I am not really an expert, more like a hobbyist ;) The guide is coming soon.

8 hours ago, Joel Bodenmann said:

In general: Just don't add any files you're not explicitly being told to add.

Exactly, the only thing you should add is the 'gfx_mk.c' and the drivers you want for your project. So first go back to the initial stat where you excluded everything except that file. Now into your project properties go back to 'Paths and Symbols -> Source location' and edit the uGFX filter you've added.

Remove_from_filter.png.be45421c93a492bf6837a82df5d80778.png

Here remove the 'drivers/' entry.

Now choose 'Add Multiple' again and exclude everything in the 'drivers' folder except for your driver like this:

Exclude_all_but_ST7656.thumb.png.837d212b74c4a2905d5357ec5377cf3b.png

Don't forget to exclude ginput, gadc,...

The last step to get it working is to add the folder 'drivers/gdisp/ST7565' to your include paths:

Include_driver_directory.png.e579cb0c6990d106a0e563b95cfa7c43.png

Do this for all three languages!

driver_active.thumb.png.86e059edc2ad929fafe677d7a30912ae.png

This should be the result in your uGFX directory.

What you also must do is copy your own made board file for the ST7565 to your includes directory.

Add_board_file.thumb.png.9cb6195b84a898ae00e91f74cdcb4148.png

This should compile and work as expected. Note that it doesn't compile for me because I haven't setup GOS correctly.

Link to comment
Share on other sites

Hi @cpu20,

Quote

Exactly, the only thing you should add is the 'gfx_mk.c' and the drivers you want for your project. So first go back to the initial stat where you excluded everything except that file.

Done.

Quote

Now into your project properties go back to 'Paths and Symbols -> Source location' and edit the uGFX filter you've added.

Here remove the 'drivers/' entry.

Now choose 'Add Multiple' again and exclude everything in the 'drivers' folder except for your driver

Don't forget to exclude ginput, gadc,...

Done.

Quote

The last step to get it working is to add the folder 'drivers/gdisp/ST7565' to your include paths.

Do this for all three languages!

Done.

 

After that, I set the following configs in the gfxconf.h:

#define GFX_USE_GDISP                                TRUE

#define GDISP_TOTAL_DISPLAYS                         1

#define GDISP_DRIVER_LIST                            GDISPVMT_ST7565

#define GDISP_PIXELFORMAT                    GDISP_PIXELFORMAT_RGB888 (My display is monochrome, but the compiler was demanding some definition here)

 

After all the steps, the code compiled.

 

Then, I ran this code:

    gfxInit();

    // Get the screen size
    width = gdispGetWidth();
    height = gdispGetHeight();

 

Results are:

width = 28209

height = 0

 

As far I could understand, when I am using only one display, the display info is load in the "GDisplay    *GDISP;".

So, functions like gdispGetWidth() run like this:

#define gdispGetWidth()                                gdispGGetWidth(GDISP)

 

But my GDISP variable looks wrong:

GDISP.JPG.4f7a9ebfc049ad0686e6cedba0cc1c32.JPG

 

EDIT:

Debugging the initialization, I realized that the driver register function is returning after trying to alloc.code_return.JPG.b5c3cf53efdc78ab663ea00632680a58.JPG 

 

Regarding the gfxAlloc(), I have added this to my gos_threadx.h:

#define GOS_NEED_X_HEAP TRUE
#include "gos_x_heap.h"

// #define gfxAlloc(sz)                pvPortMalloc(sz) // COMMENTED!
// #define gfxFree(ptr)                vPortFree(ptr) // COMMENTED!

And in the gfxconf.h:

#define GFX_OS_HEAP_SIZE                         4096

 

Is anything else needed?

Edited by Mad River
Link to comment
Share on other sites

Well,

I added _gosHeapInit() to the gos initialization and now it can successfully call gfxAlloc().

#if GFX_USE_OS_THREADX

void _gosInit(void)
{
    #if GFX_OS_NO_INIT && !GFX_OS_INIT_NO_WARNING
        #warning "GOS: Operating System initialization has been turned off. Make sure you call tx_kernel_enter()."
    #endif

    // Set up the heap allocator
    _gosHeapInit();
}

Link to comment
Share on other sites

Everything is compiling now.

width = gdispGetWidth();
height = gdispGetHeight();

Above is returning 128 x 64, as expected.

Now, I added:

#define GDISP_NEED_AUTOFLUSH                         TRUE

#define GDISP_NEED_VALIDATION                        TRUE
#define GDISP_NEED_CLIP                              TRUE

    gdispDrawBox(10, 10, width/2, height/2, Black);
    gdispFillArea(width/2, height/2, width/2-10, height/2-10, Black);
    gdispDrawLine(5, 30, width-50, height-40, Black);

 

But nothing is shown on the display.

I tested it again with another library and the hardware is working.

 

Is any more config needed to show the requested drawings in the display?

 

Link to comment
Share on other sites

I checked the signals (RST, CS, A0, Data) and the communication with the display is ok.

The problem is that the data sent to the display is all zeros.

 

Is the screen buffer the GDisplay.priv pointer?

Looking at the memory area pointed for this all is set to zeros.

 

What can I do to check if the drawing functions are correctly writing to the buffer?

Link to comment
Share on other sites

Hi @Joel Bodenmann,

 

LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
    // The private area is the display surface.
    g->priv = gfxAlloc(GDISP_SCREEN_HEIGHT * GDISP_SCREEN_WIDTH / 8);
    if (!g->priv) {
        return FALSE;
    }

 

This gfxAlloc works ok. It allocates 1024 bytes for the display.

 

Edited by Mad River
Link to comment
Share on other sites

@Joel Bodenmann,

Sorry, I edited my previous post before seeing your reply.

Anyway, the gfxAlloc works.

 

I am using monochrome and trying to write Black. Is it correct?

#define GDISP_PIXELFORMAT                    GDISP_PIXELFORMAT_MONO

gdispDrawBox(10, 10, width/2, height/2, Black);

Edited by Mad River
Link to comment
Share on other sites

gdispSetBacklight(50);  // set backlight to 50%
gdispSetContrast(50);   // set contrast to 50%

You can also change brightness and contrast at runtime with these functions.

Good to see you got it working!!!

Edited by cpu20
Link to comment
Share on other sites

Hi @cpu20 and @Joel Bodenmann,

Is there a way to define where the coordinate (0,0) should be?

I am running this code here:

    gdispFillString(0, 0, line1, font, White, Black); // Draw a text at coordinate (0,0)
    gdispDrawCircle(width-15, height-15, 10, White); // Draw a circle at the bottom right side of the display
    gdispDrawBox(0, 0, width/2, height/2, White); // Draw a box at coordinate (0,0)

 

I was expecting to see this:

expected.thumb.jpg.5ca9cdcbc9958a309c8a05d651583d48.jpg

But the display shows:

display.thumb.jpg.ae91bb70027307d28e56fb7f6b054206.jpg

 

Even if I rotate it 180º it won't be correct:

display_180.thumb.jpg.a16330fb2ea4788fd6a81ff708bdaae6.jpg

 

Link to comment
Share on other sites

That has nothing to do with rotation. That's because the manufacturer of the display module has different options/choices how to connect the display panel to the display controller. Higher developed GDISP drivers such as the SSD1963 have a configuration flag that allows inverting the long the X and Y axis if required. It appears that the author of the ST7565 driver didn't implement that. If you want to handle this properly then that's the way to go.

Quickly looking through the driver I see that things like the display inversion (positive / negative display mode) are hardcoded. These things should be passed through the GDISP control interface. The SSD1306 driver shows how to do that.

Link to comment
Share on other sites

Hi @cpu20,

Have you finished testing the uGFX in Eclipse?

I am getting a wierd behaviour from my Eclipse.

The IDE is graying out code that should be "visible". The wierd thing is that the IDE is doing it to some parts and not for others.

Below you can see a example of it:

I have defined:

#define GDISP_NEED_CLIP                              TRUE
#define GDISP_NEED_CIRCLE                            TRUE
#define GDISP_NEED_DUALCIRCLE                        TRUE
#define GDISP_NEED_ELLIPSE                           TRUE
#define GDISP_NEED_ARC                               TRUE
#define GDISP_NEED_ARCSECTORS                        TRUE

Then, in the gdisp.h, it is showing the GDISP_NEED_CLIP code, but not the others:

if_error.thumb.JPG.d626cdbcca2bb3bb409d71b0b1579e81.JPG

 

The program works. I can compile it, load the program and draw boxes and circles.

But, as it is grayed out, I can't use functions like "go to definition" or even set breakpoints in the grayed code.

Besides that, it became very hard to scroll trought the code and see whats is really being used and what is not.

Link to comment
Share on other sites

Hi @Joel Bodenmann,

In order to solve the mirrored display problem, I made a few modifications to the pixel drawing function of your library.

It worked, but I wasn't satisfied.

So, I started looking in the internet for a way to flip the content of the display through commands.

I found a function in another library that allows to flip the mirrored display using a command:

/*----------------------------
Func: view
Desc: ssets the display viewing direction
Vars: direction (top view 0xC8, bottom view (default) = 0xC0)
------------------------------*/
void dog_7565R::view(byte direction)  
{
    if(direction == VIEW_TOP)
    {
        top_view = true;
        command(0xA0);
    }
    else
    {
        top_view = false;
        command(0xA1);
    }
    
    command(direction);
    
    clear(); //Clear screen, as old content is not usable (mirrored)
}

 

I already tested it here and it works perfectly without any modifications to your drawing pixel function.

I am using your library as it is.

I believe this function can be included in your product.

 

Edited by Mad River
Link to comment
Share on other sites

2 hours ago, Mad River said:

Have you finished testing the uGFX in Eclipse?

I am getting a wierd behaviour from my Eclipse.

The IDE is graying out code that should be "visible". The wierd thing is that the IDE is doing it to some parts and not for others.

First note that this is a build in function of Eclipse and it has nothing to do with how the project is compiled.
What Eclipse does is look at the paths defined in 'properties -> C/C++ General -> Paths and Symbols -> Includes' under the GNU C language tab. Eclipse will look at every define found in the files located at these paths. So if the path where your 'gfxconf.h' is located is defined here this should work fine.
If not maybe try indexing the project with 'Index -> Rebuild'.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...