-
Posts
2,639 -
Joined
-
Last visited
-
Days Won
2
Content Type
Forums
Store
Downloads
Blogs
Everything posted by Joel Bodenmann
-
Please read the documentation and have a look at the various examples. Apparently you're trying to compile keyboard stuff without having a keyboard driver (eg. a GINPUT keyboard driver or a virtual on-screen keyboard widget).
-
Those functions belong to the GOS module and are used to interface the underlying system that µGFX is running on. gfxSystemTicks() is supposed to return the current systick value. gfxMillisecondsToTicks() is supposed to convert the number of milliseconds passed as an argument to number of system ticks. Those functions need to be implemented by the GOS port. All existing ports already have them implemented so if you're using an existing port like FreeRTOS, Linux, eCOS or anything else listed as supported you don't need to do anything. There are only two scenarios where you need to implement them yourself: You write a new port for a system that's not supported yet or you're using the baremetal port (RAW32). The API docs of those functions can be found here: https://api.ugfx.io/group___g_o_s.html The documentation for the RAW32 implementation can be found here: https://wiki.ugfx.io/index.php/BareMetal
-
How to create a new Widget with a button?
Joel Bodenmann replied to dragonzhang's topic in Development and Feedback
When using the tabset widget you should use the tabset widget high level API. There's gwinTabsetSetTab() for that. There are more goodies that you can find in the API documentation. -
How to create a new Widget with a button?
Joel Bodenmann replied to dragonzhang's topic in Development and Feedback
Well, just call gwinXxxCreate() to create your widget when you receive the button press/release event. However, this is usually bad practice. When you have enough resources (mainly talking about RAM) you create all the widgets you need during startup/initialization and then you just use gwinShow() and gwinHide() to display the widgets correctly. The handling of touch inputs and so on is all handled through the GWIN visibility and enabled state. -
Glad to hear that you got it working! Yes, that's already implemented. Just assign the toggle(s) to the list widget Yes, selecting an item via a toggle is also already implemented. Of course, you'll have to do the "switching to another list" part yourself - just as you'd have to do with a touchscreen implementation. I don't think that the default list widget has a toggle input for that as it's not really the list's job. Instead, just assign a toggle to some other event (you can manually fire the event) to get a "BACK" event just as you're getting "UP", "DOWN" and "SELECT" events already from the list itself.
-
I haven't checked your board file but when it comes to testing you can either assign the toggle to a widget (eg. pushbutton widgets accept toggle roles) and see whether the button visibly changes state. Other than that you can just setup a listener for toggle events yourself and check whether you receive anything. Thinking of this... you can also just call ginputGetToggleStatus() in your application to poll the state
-
We need you to answer my question. If you use a custom rendering function we need to see the entire function implementation.
-
Can you please show us a screenshot illustrating the problem? I'm confused: Are you using the default rendering function or a custom one?
-
Hi, I assume that the GINPUT toggle interface is best suited for it. It's very easy to to add it. It's similar to GDISP and GINPUT: There's a general part of code which provides all the high-level API. Then there's a driver and a board file that you need to implement. You can have a look at the existing implementations. You'll also find some more info on this forum.
-
You seriously need to start listening to what we're saying. It seems that you're ignoring everything we say in all your topics. If you're having troubles with the language please have a friend translate it for you. But we definitely can't help you like this.
-
I have no idea what delay_ms() is but I assume it's a delay function of your underlying system. And in that case it's completely at the wrong place. The function gfxMillisecondsToTicks() is supposed to convert the passed number of milliseconds to the number of ticks. You can find examples of how to do that using the ST CubeHAL here: https://wiki.ugfx.io/index.php/BareMetal#SysTick All other underlying systems (eg. operating systems) already have everything built-in.
-
Seems like you're making progress - good work. Now you need to verify whether the signals are really doing what the display controller expects (and there's not really much that can go wrong like with SPI modes or so on). Once you're sure that your waveforms look right you can just go back to your uGFX stuff and implement the board file / driver. Timings should not be of a concern at this stage. Usually you set them very low (or rather high, depending on your point of view) intentionally just to be sure that it won't be a limiting factor. Once you have everything running you can start dialing the timings to find the sweet spot.
-
I didn't carefully check every line of your code but I assume that the compiler is simply optimizing it out because you always change fsc[0] (this might be wrong if you setup volatile pointers correctly and so on, I barely skimmed your code). Try to write to different FMC target locations. Also, disabling compiler optimization completely is always a good help in these kinds of debugging / boot-strapping situations.
-
Hello @quipu and welcome to the µGFX community! As @aeroman already mentioned the problem is that the changes are not being flushed to the real display. The UC1610 GDISP driver needs to maintain an internal framebuffer as the display controller doesn't provide one that allows addressing each pixel individually. Therefore, when rendering you always modify the framebuffer inside your microcontroller's RAM. The framebuffer contents need to be actively pushed to the UC1610 display controller. This is done by what's called "flushing" in the GDISP module. There are multiple ways to flush: Manually call gdispFlush() Use auto flushing (can be enabled in the configuration file) Use a flush timer (can be enabled in the configuration file) I hope that helps.
-
Great!
-
I agree that the best solution is to run your µGFX computer on a desktop machine as suggested by @inmarket. µGFX is fully portable. You can take your microcontroller application and compile it to a native Windows / Linux / MacOS application. Of course, if you did your software design right you can just copy paste the entire thing. Otherwise, just copy the GUI parts.
-
Hello @youqun and welcome to the µGFX community! The font converter is now up again. We did a lot of reconfiguration in our network lately and this one must have been missed out. Please excuse the inconvenience. Pro tip: The new µGFX-Studio has a built-in font converter.
-
https://wiki.ugfx.io/index.php/Pixmaps https://wiki.ugfx.io/index.php/Multiple_displays Yes. that is correct. It cannot be disabled. It's a built-in feature. This allows for a much smaller and faster window manager. You cannot hide a background (container) without overwriting the area because you can't delete something from the display - you need to overwrite it. You can use doublebuffering as explained in my previous post to prevent things like this (there are many other additional things such as TE integration and so on).
-
I'd just like to add that µGFX still has everything you need to read back the framebuffer. So if you GDISP driver and/or your hardware supports it, you can use GDISP high-level API to read back the framebuffer and write it to an image. Another alternative for a GWIN based application is to render everything into a pixmap. If you have a top-level container you can just change the display pointer to render into the pixmap. The pixmap itself already supports writing to an image. Here's a forum post regarding rendering to GWIN stuff to a pixmap:
-
To save a lot of resources (especially RAM and also CPU time).
-
This is the relevant code taken from the µGFX-Studio v0.22.4: void UGfxWindow::setDisplay(GDisplay* g) { if (!_ghandle) { return; } // Nullptr means default/standard display if (!g) { g = GDISP; } gwinHide(_ghandle); _ghandle->display = g; gwinShow(_ghandle); } _handle is the GHandle.
-
There's no hacking involved. You just need to change the GDisplay* pointer. We did the same thing for the µGFX-Studio.
-
Hi, The most common solution is (as you mentioned) double buffer. However, proper double buffering is very hard to implement and also requires hardware support. While µGFX can fully support double buffering (with the multiple displays API) we do also provide you with a more flexible way: Pixmaps. You can simply render your widget into a pixmap and then blit that pixmap to your real display. Pixmaps have certain advantages over real double buffering. The most notable is that you don't need two times the memory for the entire display area - a pixmap can be just a small portion of the screen. Other than that there are other things which vastly improve these sort of things such as anti-tearing-effect flags and so on. But all of that needs to be supported by the hardware.
-
The SSD1963 has an R/S pin which is used to tell the display controller whether the incoming data is configuration data or actual pixel data. This is done so that you don't need to wire up all the address pins in order to address each pixel individually (and each configuration register). The two macros above are used to access the SSD1963's memory, one time with R/S set to 0 and one time set to 1 - essentially giving you the option to write pixel data or configuration using "stock FSMC" without having to manually control the R/S pin via a GPIO. You need to ensure that the macro which sets the R/S pin has the correct address. So if you hooked the R/S pin up to FSMC_A16 you need to sure that GDISP_RAM has address bit 16 (the 17th bit) set to 1. FSMC is usually extremely straight forward and there is little that can go wrong. Just make sure that you use low timings until everything is working. Then you can ramp them up. But usually you want to be somewhere in the range of 10k to 100k until everything works. Also make sure that your pins are setup correctly (that the correct pins are being set to alternate function and so on). The most difficult part with the SSD1963 is getting the panel parameters correct. Make sure that you always at least tripple-check them. Those parameters are different for each panel. You should get a table of values together with your panel. However, note that the parameters you get are not always the ones you need to enter into that parameter struct. They are often calculated differently. I know that this post isn't as helpful as you might have wished for but there's not much we can do. FSMC is pretty much self contained: It's all about accessing a memory region. Everything else is up to your hardware and proper pin configuration. Simply tripple-check everything, take a break and do it again. Also, you definitely want to use a scope or logic analyzer to have a peek at those FSMC pins. Keep in mind that you can test the FSMC outside of µGFX. All that FSMC is doing is accessing a memory region. Therefore, you can setup your pins and just try accessing the SSD1963 with the two macros above - no magic involved. You can then just make call to the one with R/S = 0 and one with R/S = 1 in the main loop and use a scope or logic analyzer to verify that the correct pin is toggling.
-
GWidgetObject is the base widget call: https://git.ugfx.io/uGFX/uGFX/src/master/src/gwin/gwin_widget.h#L109 You don't usually worry about those as you always access them using the GHandle. Edit: Yes, GWidgetObjset is definitely a spelling error.