Jump to content

GDISPVMT_pixmap missing


JakeSays

Recommended Posts

Hello and welcome to the community!

Is it possible that you just forgot to enable pixmaps in your configuration file by setting GDISP_NEED_PIXMAP to TRUE?

Otherwise, can you please show us the complete compiler output log? You definitely shouldn't get any error about LLDSPEC in any case.

Just to be sure: Did you manage to draw to your display without using the pixmaps so far?

Can you please also provide information about the IDE and the compiler that you are using along with the compiler output log?

~ Tectu

Link to comment
Share on other sites

Hey thanks for the response :)

Here's a link to my compiler output: http://pastebin.com/62YQYDuZ

Also I do have GDISP_NEED_PIXMAP defined to TRUE.

My target environment is a raspberry pi via direct SPI access to an Adafruit PiTFT 2.8" display. Both the LCD and touch screen use SPI.

I can get the basic demo to work just fine using the ILI9341 driver. My bigger issue is getting the touch screen to work. The driver is an STMPE610, so I've been trying to get the '610 support in uGFX to work. Using a pixmap as an intermediate framebuffer is an experiment to work around the two controllers fighting over the SPI bus.

In regard to GDISPVMT_pixmap and LLDSPEC missing, I cannot locate them in the source tree using grep.

Thanks,

-Jake

Link to comment
Share on other sites

I can get the basic demo to work just fine using the ILI9341 driver. My bigger issue is getting the touch screen to work. The driver is an STMPE610, so I've been trying to get the '610 support in uGFX to work. Using a pixmap as an intermediate framebuffer is an experiment to work around the two controllers fighting over the SPI bus.

Just that we understand us correctly - you should be able to get this setup working without using pixmaps. For optimization that's definitely a good way to go but it should definitely also work without it.

If you are having trouble getting the basic setup working without the pixmaps please do not hesitate to ask. We are happy to help where we can.

You should be able to even use different bus speeds for the two by changing the SPI configuration in the acquire_bus() function so the board files.

In regard to GDISPVMT_pixmap and LLDSPEC missing, I cannot locate them in the source tree using grep.

GDISPVMT_pixmap is line 33 of /src/gdisp/gdisp_pixmap.c.

LLDSPEC is line 413 and 415 of /src/gdisp/gdisp_driver.h. All that does is either adding nothing or 'static' depending on whether you use just one or multiple displays.

Judging from the compiler output you are lacking the inclusion of some files. Can you give some information about the build environment and the toolchain that you are using? Eg. are you using a makefile or the single-file inclusion etc.

As this seems to be a bitbucket repository - is it possible that we get access to it so we can give the configuration a quick look?

Please make sure that you use the latest master of the uGFX repository and that you integrated the uGFX library into your existing RPi project using either of these two methods: http://wiki.ugfx.org/index.php?title=Ge ... grate_uGFX

~ Tectu

Link to comment
Share on other sites

Using the uGFX ILI9341 driver I can draw on the LCD just fine.

here is line 33 of gdisp_pixmap.c: #define GDISP_DRIVER_VMT GDISPVMT_pixmap

GDISPVMT_pixmap is not defined anywhere, which causes the compile error.

My environment is:

Host:

Windows 10, VisualGDB, Visual studio 2015. Using visualgdb. I cross compile using their raspberry pi toolchain. This works fine as I have written several apps using it.

Target:

Raspberry Pi2, Raspbian jessie.

Also, I'm using the all-in-one build method (ie no make files)

I tried using acquire/release_bus() to isolate the two controllers from each other (using a gfxMutex), and change speed. When I do this drawing performance tanks and then eventually stops all together.

The bitbucket repo (https://bitbucket.org/jakesays/ugfx is public, but currently it is a direct mirror of yours.

One more thing: the motivation for going down the direct SPI route is the linux framebuffer driver doesn't support RGB565. If it did I'd use that.

Thanks :)

-Jake

Link to comment
Share on other sites

Actually its not a missing header issue. It's related to the single file build method.

For some reason GDISP_DRIVER_VMT is undefined when gdisp_driver.h is included in gdisp_pixmap.c

If I comment out gdisp_pixmap.c from gdisp_mk.c and add gdisp_pixmap.c directly to my project the GDISPVMT_pixmap related errors go away.

However now I'm getting "GDISP: Unsupported color system for low level drivers" :( it appears RGB565 is not supported in a lot of places.

Link to comment
Share on other sites

The single file build doesn't support multiple displays yet or some of the other 3rd party library thunks (such as TinyGL).

The pixmap code internally uses the multiple display handling and therefore doesn't compile with the single file build.

To get this to work you will need to include all the appropriate individual ugfx files instead of just gfx_make.c. An easy way to do this is to use our makefile system.

While this would be nice to fix it is currently not high on our development agenda as:

  • there are alternative build methods that do work,
  • it is actually quite complex to fix and,
  • our development has a big backlog of other work.

Link to comment
Share on other sites

With regard to the bus conflict across the two device types (LCD vs TOUCH), the correct place to fix this is in the aquirebus/releasebus calls.

The trick is not to really acquire access to the SPI which on some operating systems can be very slow, but to instead create your own mutex and use that to arbitrate access.

In most situations that should be a lot faster as it is not having to reinitialise the hardware and mutexes generally have little performance hit unless a busy mutex is hit.

eg..

Note the below is pseudo code.

In your display driver board file:


board_init() {
....
gfxMutexInit(&myMutex);
...
}
aquirebus() { gfxMutexEnter(&myMutex); set your CS pin for display }
releasebus() { gfxMutexExit(&myMutex); }

In your touch driver board file:


aquirebus() { gfxMutexEnter(&myMutex); set your CS pin for touch }
releasebus() { gfxMutexExit(&myMutex); }

Of course, if you are using a non-preemptive operating system (like RAW32) there is no need to have the mutex (unless you are using GDISP streaming API). It will all just work with just setting the CS pin appropriately.

Link to comment
Share on other sites

Ok I think I may have coded myself in to a rat hole here. I'll explain what it is I'm trying to do and perhaps you guys could provide some guidance?

I have a Raspberry Pi 2 B and an adafruit 2.8" lcd/touch screen. The lcd is controlled by an ILI9341, and the ts by an STMPE610. The device also exposes the STMPE610 interrupt line.

My goal is to get uGFX to work with both the lcd and ts. Also I cannot use the framebuffer because the uGFX framebuffer driver does not support RGB565.

What would be the suggested way to proceed?

I really appreciate all your help :)

-Jake

Link to comment
Share on other sites

I am familiar with the particular board you are using as I have one myself. I haven't yet tried to drive the raspberry pi and the ardafruit display/touch together yet.

The uGFX framebuffer does support RGB565 - in fact it is the most commonly used format pixel format for the framebuffer. The framebuffer is capable of supporting any non-palletised pixel format with 8 to 32 bits per pixel.

The framebuffer driver is actually used by the raspberry pi HDMI display by default in RGB565 format! See boards/base/RaspberryPi/board_framebuffer.h

Note that when running multiple displays there is no problem with the multiple displays having different pixel formats. In a multiple display situation the system pixel format is chosen separately from the hardware display formats and the hardware drivers convert the pixel format as needed. For efficiency it is however best to use a system pixel format common to at least one of the displays. For single display systems the system pixel format always matches the display pixel format.

There are two problems that you appear to currently have...

1. The usage of the same SPI port by the lcd and the touch panel. This is solved using the aquirebus/releasebus mechanism described in the previous post.

2. The compile errors you are getting. This is caused by using the single file build mechanism along with multiple display functionality. The ONLY way to solve this if you want to drive both the pi HDMI display and the Ardafruit display is to use the makefile build method. Of course if you turn off the pi HDMI display you could continue to use the single file build mechanism.

In conclusion,

  • the problems you are seeing with "RGB565" and the pixmap errors are all related to #2 above.
  • The problems to do with a single SPI port being used by the lcd and touch are related to #1 above.
  • Pixmaps are really nothing to do with what you are trying to achieve here. They are only confusing the real issues. Please turn them off until you have the displays working properly and then only turn them on if you really want the functionality pixmaps provide.

If you are still confused attach your project as a zip file and I will have a look but please make sure you have addressed the issues above first.

Link to comment
Share on other sites

The uGFX framebuffer does support RGB565 - in fact it is the most commonly used format pixel format for the framebuffer. The framebuffer is capable of supporting any non-palletised pixel format with 8 to 32 bits per pixel.

The framebuffer driver is actually used by the raspberry pi HDMI display by default in RGB565 format! See boards/base/RaspberryPi/board_framebuffer.h

I tried using the frame buffer, but when it ran I got an incompatible color format error. I should mention though that I'm using the custom framebuffer (fbtft) from adafruit.

Note that when running multiple displays there is no problem with the multiple displays having different pixel formats. In a multiple display situation the system pixel format is chosen separately from the hardware display formats and the hardware drivers convert the pixel format as needed. For efficiency it is however best to use a system pixel format common to at least one of the displays. For single display systems the system pixel format always matches the display pixel format.

I only need to support the PiTFT as the environment is embedded.

1. The usage of the same SPI port by the lcd and the touch panel. This is solved using the aquirebus/releasebus mechanism described in the previous post.

I added a mutex and locked/unlocked in aquirebus/releasebus, but ran in to huge lock contention issues when I enabled the touch screen. Drawing speed slowed to the point where there was seconds between each pixel being rendered while drawing the calibration screen.

2. The compile errors you are getting. This is caused by using the single file build mechanism along with multiple display functionality. The ONLY way to solve this if you want to drive both the pi HDMI display and the Ardafruit display is to use the makefile build method. Of course if you turn off the pi HDMI display you could continue to use the single file build mechanism.

A lot of those errors were unrelated. I should've cleaned it up before posting. I was in experiment mode.

In conclusion,

  • the problems you are seeing with "RGB565" and the pixmap errors are all related to #2 above.
  • The problems to do with a single SPI port being used by the lcd and touch are related to #1 above.
  • Pixmaps are really nothing to do with what you are trying to achieve here. They are only confusing the real issues. Please turn them off until you have the displays working properly and then only turn them on if you really want the functionality pixmaps provide.

I'm going to give these a try with a fresh code base.

Thanks! :)

Link to comment
Share on other sites

With regard to the contention and slow drawing during calibration - this is because calibration polls the touch screen as fast as it can and this is causing there to be no time left for the lcd display. Note this is only an issue during calibration as everything is timer based thereafter.

The solution is to put a gfxSleepMilliseconds(1) just before the gfxMutexEnter() in the acquire routine in the touch board file.

This will allow the LCD an opportunity to respond without affecting the performance of the touch very much at all as the touch really only needs to be polled once every 50ms or so even for really great responsiveness.

There is also a timer associated with the poll whose period is set by the GINPUT_MOUSE_POLL_PERIOD gfxconf setting. This defaults to 25ms. Try increasing that period. Settings as high as 250ms should still give good touch responsiveness.

Note that interrupt handling for all the touch controllers implemented so far is turned off in each driver (if implemented at all) as every controller we have tried to date has had serious bugs in the controller relating to the interrupt.

Link to comment
Share on other sites

Ahh, just noticed the new piece of information you provided...

If you are using a Linux kernel framebuffer driver eg fbtft rather than driving the hardware directly then you should be using the Linux-Framebuffer code found in board/base/Linux-Framebuffer instead of the Raspberry Pi specific code which is all about drivng the Pi HDMI port. The Linux-Framebuffer code internally uses the ugfx generic framebuffer driver.

In the board_framebuffer.h at the top you will see you need to define your pixel format and the fb device name. The pixel format defaults to RGB888 if you don't specify a value. This value must exactly match the mode of your Linux kernel level driver. If the Adafruit hardware and the Linux kernel driver run at RGB565 then you need to put something like:


#define GDISP_LLD_PIXELFORMAT GDISP_PIXELFORMAT_RGB565

into your gfxconf.h file or in the top of your board_framebuffer.h

If this is your situation, you probably don't need to worry about the SPI bus contention at all as the SPI bus is only used by the adafruit lcd to initialise the controller chip. Thereafter everything is done through memory mapping. In that situation the display is already initialised long before the touch starts running.

Link to comment
Share on other sites

You might want to store your calibration values once you performed the calibration. This way you can 'boot up' (starting uGFX by calling gfxInit()) without the need to calibrate again.

Information on how to use the calibration interface can be found here: http://wiki.ugfx.org/index.php?title=To ... alibration

~ Tectu

Now that I have the framebuffer working I've gone back to using the adafruit kernel drivers. The drivers handle calibration so I think I'm ok there.

However the next issue I'm facing is how do I read the touch screen values?

From what I've gathered from the ugfx source I'll need to write a ginput driver that pulls events from /dev/input/touchscreen, which is how the adafruit stmpe driver exposes events.

The format of the events is straight forward. Here's sample output from evtest /dev/input/touchscreen:

Event: time 1451488716.725099, type 3 (EV_ABS), code 0 (ABS_X), value 1925
Event: time 1451488716.725099, type 3 (EV_ABS), code 1 (ABS_Y), value 2226
Event: time 1451488716.725099, type 3 (EV_ABS), code 24 (ABS_PRESSURE), value 137
Event: time 1451488716.725099, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 1
Event: time 1451488716.725099, -------------- EV_SYN ------------
Event: time 1451488716.781826, type 3 (EV_ABS), code 24 (ABS_PRESSURE), value 0
Event: time 1451488716.781826, type 1 (EV_KEY), code 330 (BTN_TOUCH), value 0
Event: time 1451488716.781826, -------------- EV_SYN ------------

Am I on the right track? Also, what is a toggle input device?

Thanks,

-Jake

Link to comment
Share on other sites

Sadly he's not able to help as he's currently on a trip (vacation). However, he sent me the files attached (GINPUT driver, board file, test project).

He used this on a 3.2 Linux. The uGFX version he used this with was something between 2.3 and 2.4.

I hope that helps you somehow... Please let us know how this turns out.

~ Tectu

linux_ginput_event.zip

Link to comment
Share on other sites

Thanks much for the code.

It was educational but not complete enough to work.

But it was very helpful in writing my own driver.

So as it stands I now have both the display and touch working!

Would you be interested in a pull request for this specific card?

Thanks again for all your help :)

-Jake

Link to comment
Share on other sites

  • 1 month later...

Hello!

I am using ugfx with an SSD1351 and Teensy3.1 (thanks to Christoph aka crteensy) and it works fine without using pixmaps, but I get the same errors when I enable pixmaps in my gfxconf.h file:

#define GDISP_NEED_PIXMAP			TRUE

Here are some of the errors I am running into:



In file included from /Users/tenkai/Desktop/Projects/Arduino/libraries/ugfx/src/gdisp/gdisp_mk.c:23:0,
from /Users/tenkai/Desktop/Projects/Arduino/libraries/ugfx/src/gfx_mk.c:12,
from /Users/tenkai/Desktop/Projects/Arduino/libraries/ugfx-arduino/ugfx-arduino.c:1:
/Users/tenkai/Desktop/Projects/Arduino/libraries/ugfx/src/gdisp/gdisp_pixmap.c: In function 'gdispPixmapCreate':
/Users/tenkai/Desktop/Projects/Arduino/libraries/ugfx/src/gdisp/gdisp_pixmap.c:83:35: error: 'GDISPVMT_pixmap' undeclared (first use in this function)
g = (GDisplay *)gdriverRegister(&GDISPVMT_pixmap->d, p);
^
/Users/tenkai/Desktop/Projects/Arduino/libraries/ugfx/src/gdisp/gdisp_pixmap.c:83:35: note: each undeclared identifier is reported only once for each function it appears in
/Users/tenkai/Desktop/Projects/Arduino/libraries/ugfx/src/gdisp/gdisp_pixmap.c: In function 'gdispPixmapDelete':
/Users/tenkai/Desktop/Projects/Arduino/libraries/ugfx/src/gdisp/gdisp_pixmap.c:90:17: error: 'GDISPVMT_pixmap' undeclared (first use in this function)
if (gvmt(g) != GDISPVMT_pixmap)
^
/Users/tenkai/Desktop/Projects/Arduino/libraries/ugfx/src/gdisp/gdisp_pixmap.c: In function 'gdispPixmapGetBits':
/Users/tenkai/Desktop/Projects/Arduino/libraries/ugfx/src/gdisp/gdisp_pixmap.c:96:17: error: 'GDISPVMT_pixmap' undeclared (first use in this function)
if (gvmt(g) != GDISPVMT_pixmap)
^
/Users/tenkai/Desktop/Projects/Arduino/libraries/ugfx/src/gdisp/gdisp_pixmap.c: At top level:
/Users/tenkai/Desktop/Projects/Arduino/libraries/ugfx/src/gdisp/gdisp_pixmap.c:113:1: error: unknown type name 'LLDSPEC'
LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
^
In file included from /Users/tenkai/Desktop/Projects/Arduino/libraries/ugfx/src/gdisp/gdisp.c:13:0,
from /Users/tenkai/Desktop/Projects/Arduino/libraries/ugfx/src/gdisp/gdisp_mk.c:21,
from /Users/tenkai/Desktop/Projects/Arduino/libraries/ugfx/src/gfx_mk.c:12,
from /Users/tenkai/Desktop/Projects/Arduino/libraries/ugfx-arduino/ugfx-arduino.c:1:
/Users/tenkai/Desktop/Projects/Arduino/libraries/ugfx/src/gdisp/gdisp_driver.h:318:21: error: expected declaration specifiers or '...' before '(' token
#define gvmt(g) ((const GDISPVMT const *)((g)->d.vmt)) // For ease of access to the vmt member
^
/Users/tenkai/Desktop/Projects/Arduino/libraries/ugfx/src/gdisp/gdisp_driver.h:677:31: note: in expansion of macro 'gvmt'
#define gdisp_lld_init(g) gvmt(g)->init(g)
^
/Users/tenkai/Desktop/Projects/Arduino/libraries/ugfx/src/gdisp/gdisp_pixmap.c:113:16: note: in expansion of macro 'gdisp_lld_init'
LLDSPEC bool_t gdisp_lld_init(GDisplay *g) {
^
In file included from /Users/tenkai/Desktop/Projects/Arduino/libraries/ugfx/src/gdisp/gdisp_mk.c:23:0,
from /Users/tenkai/Desktop/Projects/Arduino/libraries/ugfx/src/gfx_mk.c:12,
from /Users/tenkai/Desktop/Projects/Arduino/libraries/ugfx-arduino/ugfx-arduino.c:1:
/Users/tenkai/Desktop/Projects/Arduino/libraries/ugfx/src/gdisp/gdisp_pixmap.c:132:9: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'void'
LLDSPEC void gdisp_lld_deinit(GDisplay *g) {
^
/Users/tenkai/Desktop/Projects/Arduino/libraries/ugfx/src/gdisp/gdisp_pixmap.c:136:9: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'void'
LLDSPEC void gdisp_lld_draw_pixel(GDisplay *g) {
^
/Users/tenkai/Desktop/Projects/Arduino/libraries/ugfx/src/gdisp/gdisp_pixmap.c:162:1: error: unknown type name 'LLDSPEC'
LLDSPEC color_t gdisp_lld_get_pixel_color(GDisplay *g) {
^
In file included from /Users/tenkai/Desktop/Projects/Arduino/libraries/ugfx/src/gdisp/gdisp.c:13:0,
from /Users/tenkai/Desktop/Projects/Arduino/libraries/ugfx/src/gdisp/gdisp_mk.c:21,
from /Users/tenkai/Desktop/Projects/Arduino/libraries/ugfx/src/gfx_mk.c:12,
from /Users/tenkai/Desktop/Projects/Arduino/libraries/ugfx-arduino/ugfx-arduino.c:1:
/Users/tenkai/Desktop/Projects/Arduino/libraries/ugfx/src/gdisp/gdisp_driver.h:318:21: error: expected declaration specifiers or '...' before '(' token
#define gvmt(g) ((const GDISPVMT const *)((g)->d.vmt)) // For ease of access to the vmt member
^
/Users/tenkai/Desktop/Projects/Arduino/libraries/ugfx/src/gdisp/gdisp_driver.h:691:39: note: in expansion of macro 'gvmt'
#define gdisp_lld_get_pixel_color(g) gvmt(g)->get(g)
^
/Users/tenkai/Desktop/Projects/Arduino/libraries/ugfx/src/gdisp/gdisp_pixmap.c:162:17: note: in expansion of macro 'gdisp_lld_get_pixel_color'
LLDSPEC color_t gdisp_lld_get_pixel_color(GDisplay *g) {
^
In file included from /Users/tenkai/Desktop/Projects/Arduino/libraries/ugfx/src/gdisp/gdisp_mk.c:23:0,
from /Users/tenkai/Desktop/Projects/Arduino/libraries/ugfx/src/gfx_mk.c:12,
from /Users/tenkai/Desktop/Projects/Arduino/libraries/ugfx-arduino/ugfx-arduino.c:1:
/Users/tenkai/Desktop/Projects/Arduino/libraries/ugfx/src/gdisp/gdisp_pixmap.c:189:10: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'void'
LLDSPEC void gdisp_lld_control(GDisplay *g) {
^
In file included from /Users/tenkai/Desktop/Projects/Arduino/libraries/ugfx/src/gdisp/gdisp_mk.c:21:0,
from /Users/tenkai/Desktop/Projects/Arduino/libraries/ugfx/src/gfx_mk.c:12,
from /Users/tenkai/Desktop/Projects/Arduino/libraries/ugfx-arduino/ugfx-arduino.c:1:
/Users/tenkai/Desktop/Projects/Arduino/libraries/ugfx/src/gdisp/gdisp.c:3178:15: warning: 'mf_drawline_callback' defined but not used [-Wunused-function]
static bool mf_drawline_callback(mf_str line, uint16_t count, void *state) {
^

So I guess I am wondering, is there anything special I need to do to use pixmaps? Do I have to use a framebuffer driver instead of the normal SSD1351 driver I am using? I have

#define GDISP_LLD_PIXELFORMAT      		GDISP_PIXELFORMAT_RGB565

defined in my gdisp_lld_config.h. I have a sneaking suspicion that it might be some include that is not working properly, or not put in the right order... What information could I provide to make solving this easier?

Thank you!

Tenkai

Link to comment
Share on other sites

This is caused by the single file make used by the arduino port. The single file make doesn't support some of the more advanced ugfx library features yet such as multiple displays. Unfortunately pixmaps internally use multiple display support.

The solution is that instead of just including the one file ugfx_mk.c into the project, each of the source files needs to be included like the traditional makefile method of building ugfx.

This is something we will eventually fix but it is currently low on our priority order as there is another way of building (albiet a more complex method) that does work for this feature.

Link to comment
Share on other sites

inmarket -

I also posted this question over at the pjrc forum:

https://forum.pjrc.com/threads/26535-uG ... able/page3

So I have been able to get ugfx to compile by including gdisp_pixmap.c manually in my configuration library, however once I compile and attempt to draw to the pixmap, nothing draws on the display. If I disable pixmaps I am able to draw directly to the display again.

I am following the code on this site: http://wiki.ugfx.org/index.php/Pixmaps

Is it possible that there are still other files I need to include manually, even though I am no longer getting any compiler warnings? Should I need to alter the driver configuration at all to handle pixmaps?

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...