Grobatt Posted February 16, 2017 Report Posted February 16, 2017 Hello all, First of all i'm totally new to uGFX. I'm working on a CC3200 from texas instruments and will need to display PNG images on a 320x240 LCD using SSD2119. I saw that uGFX include a PNG decoder and also drivers for this LCD controller, so this seems very promising. I have few questions: 1/ Has anyone already implemented uGFX on a CC3200 ? i'm quite worried about perfomances when it comes to decode a PNG and display it on such a small MCU. 2/ Can I only use one module excusively (ie. GDISP) or there are dependencies ? 2/ I'll be storing the PNG images on a SD card, along with other files (json as data base) that I need to use in my project. I'll be using FatFs to open and read the json files and wanted to also use it to read the PNG but apparently uGFX already implement a file system. So i'm wondering if I can only use GDISP module for PNG decoding and display operations or do I have to also use other modules like GFILE, GWIN, etc.. Thanks.
Joel Bodenmann Posted February 16, 2017 Report Posted February 16, 2017 Hello @Grobatt and welcome to the µGFX community! 2 hours ago, Grobatt said: 1/ Has anyone already implemented uGFX on a CC3200 ? i'm quite worried about perfomances when it comes to decode a PNG and display it on such a small MCU. Running µGFX on a CC3200 is no problem at all. After all it's a Cortex-M4 processor and µGFX runs very well on those (probably the best supported platform). You definitely won't have any issues running µGFX on it. When it comes to PNG: Just as with everything else we wrote our PNG decoder completely from scratch ourselves to ensure that everything uses as little resources as anyhow possible. However, due to how the PNG format works you require 32 kB of RAM just for the sliding window for decoding the PNG. In addition to that there's a few more kilobytes requires for the deflation buffer and similar things so all in all you need about 37 kB or RAM to display a PNG image of any size. You can find a very detailed description on the memory requirements for rendering a PNG image here: https://wiki.ugfx.io/index.php/Images#PNG In general you definitely don't want to use PNG images on any smaller embedded platform. Is there a particular reason why you'd like to use PNG images? There are plenty of other options. If you explain your use case we might be able to give you a bit more guidance. 2 hours ago, Grobatt said: 2/ Can I only use one module excusively (ie. GDISP) or there are dependencies ? Yes, you can just use the GDISP module. The configuration file allows to individually enable and disable every single module, feature and sub-feature. You can just enable the GDISP module and it doesn't have any dependencies at all. 2 hours ago, Grobatt said: 2/ I'll be storing the PNG images on a SD card, along with other files (json as data base) that I need to use in my project. I'll be using FatFs to open and read the json files and wanted to also use it to read the PNG but apparently uGFX already implement a file system. So i'm wondering if I can only use GDISP module for PNG decoding and display operations or do I have to also use other modules like GFILE, GWIN, etc.. The µGFX library is very modular. It is possible to use just the GDISP module with no other dependencies for displaying your PNG image. You have to provide the corresponding gdispImage object (struct instance) and then GDISP can display it - it doesn't bother where it comes from. However, as you mentioned µGFX provides certain mechanisms to vastly simplify this. The GFILE module provides a generic, high-level file system abstraction API. The GFILE module itself is very small and does't do anything besides providing wrapper functions. Once you enabled the GFILE module in your configuration file you can choose which file system(s) you want to be using. We do offer a FatFS wrapper that allows you to display a picture by using just two lines of code: gdispImage myImage; gdispImageOpenFile(&myImage, "/path/to/myImage.png"); gdispImageDraw(&myImage, 0, 0, swidth, sheight, 0, 0); If you prefer using something more lightweight you can have a look at ROMFS. It's a file system we wrote ourselves that allows loading any file from your ROM (eg. your micrcontrollers flash). We provide the corresponding tool called file2c that allows converting any file into a C array so you can easily include it in your microcontroller's flash image by just #including the file instead of screwing around with linker scripts. To answer your question: Yes, you can use just the GDISP module to display your PNG image. You can optionally use the GFILE module if you want to make your life easier (you can either use our built-in FatFS implementation or your own one). The GWIN module optionally offers you a window manager with widgets. There's an imagebox widget that would allow you rendering your PNG image as part of the widgets system maintained by the window manager so you don't have to manually take care of redrawing it but the GWIN system will pull in more dependencies such as the GQUEUE module (and the GINPUT, GEVENT and GTIMER module if you have touch/mouse input). But not to worry: If you really need those features then go for it. The µGFX library has been written to be as modular and as lightweight as possible. Every unused feature (and sub-feature and sub-sub-feature and ...) are excluded before compilation by means of the pre-processor. I hope that answers your questions. Please don't hesitate to ask if you have any further questions. We're happy to help!
Grobatt Posted February 17, 2017 Author Report Posted February 17, 2017 (edited) Hi Joel, Thanks for this detailed answer. I've developped a few systems but ironicaly this is the first time I deal with graphical display and still feel a bit dumb on the subject at this time. 11 hours ago, Joel Bodenmann said: Is there a particular reason why you'd like to use PNG images? There are plenty of other options. If you explain your use case we might be able to give you a bit more guidance. I scan barcodes with an optical reader, I have different images, icons, and text that I want to display depending on the object scanned. The background may have different colors for a same image/icon, so in order to don't have multiple instances of a BMP image with different background colors, it would be preferable to deal with transparency therefore using PNG, also I may end up with a lot of images and that would save some memory space. If you have any suggestion let me know :). Regards. Edited February 17, 2017 by Grobatt
Joel Bodenmann Posted February 17, 2017 Report Posted February 17, 2017 1 hour ago, Grobatt said: I've developped a few systems but ironicaly this is the first time I deal with graphical display and still feel a bit dumb on the subject at this time. There's absolutely no reason to feel dump. You cannot possibly know everything. Please don't hesitate to ask if you have any questions, we're always happy to help. 1 hour ago, Grobatt said: The background may have different colors for a same image/icon, so in order to don't have multiple instances of a BMP image with different background colors, it would be preferable to deal with transparency therefore using PNG, also I may end up with a lot of images and that would save some memory space. You might consider using GIF instead then. It's a lot easier on the CPU and requires about one fourth of the memory that you need to decode a PNG. Our GIF decoder supports transparency. Other than that the common (and strongly recommended) approach is to use bitmaps (regular BMP formats). The bitmaps that have less than or exactly 8 bits per pixel have color palettes. This way you can simply exchange the background color in the BMP before drawing it to the screen. That is how most GUIs are implemented and that is how we implement the GUIs for our customers whenever possible. BMPs come with almost no overhead at all. They are stored uncompressed but as you're talking about icons the size shouldn't be a problem. We also use the same technique for GUIs where you can change the theme (the color scheme) and when the user can click/press the icon as you can simply adjust the background color again to give it a "pressed" effect. Modifying the palette is a very fast operation as well. In the example here, we use the same bitmap (the same BMP image is only one time in the memory) and we render it with 7 different color schemes. Note that you can use bitmaps with more than just one color as well - You can do the same with "colored" icons:
steved Posted February 17, 2017 Report Posted February 17, 2017 To give you some idea of relative performance, I've just benchmarked display of a 640 x 480 image from .gif, .bmp (RLL-encoded) and .png. On a STM32F4 with 168MHz CPU clock speeds (in clock cycles) are: .gif - 114945392 .png - 298198420 .bmp - 59564728
Joel Bodenmann Posted February 17, 2017 Report Posted February 17, 2017 Thanks for sharing your results. Exactly as expected
Grobatt Posted February 17, 2017 Author Report Posted February 17, 2017 Thanks for the advice Joel. The pallette approach is very interesting. It's still early in my developement process, a lot do before I run GDISP, but this look very promising. I will keep you updated on my progress and may come back for further informations.
Joel Bodenmann Posted February 17, 2017 Report Posted February 17, 2017 Sounds good! Keep in mind that you can develop your entire µGFX application on a desktop computer as you can compile native Windows, Linux, Mac OS X and BSD applications. Those are native applications that only use the µGFX library. We don't use simulators or emulators. This means that every single pixel that you see on your desktop will be exactly the same on your hardware target afterwards.
Grobatt Posted March 17, 2017 Author Report Posted March 17, 2017 Hello Getting back to you for some news. I finally found some time last week to work a bit on this project. After spending time to learn how to work with a graphic LCD screen, I dug into uGFX to also learn about graphic library ;). Well after some basic struggle with my SPI config and screen, I have been succesfuly able to display BMP / PNG / GIF images with the CC3200 using CCSv6 as IDE, so I can confirm that uGFX is working well with this IDE (gfx_mk.c method) and armcc compiler . As I'm reading images form SD card and then using SPI for the screen, I'm a bit disappointed with the refresh speed. I guess that would be better with parallel port but sadly I'm too short in available pins. At this time I'm not sure if I'll work with BMP or PNG, if fact PNG works but a bit slower that BMP and i'm not sure I'll be able to afford the 32ko of memory needed when I'll stitch all my application together, as the CC3200 uses the 256ko of memory for code and data. So all in all, maybe I'll stick with BMP and work with the pallette to change background color as you suggested, instead of using transparency. Talking about GFILE: I use GFILE so it's easy to open and display an image, but I also need to read text file as a database, sadly I would really need f_gets ;). I saw that it's not impleted yet, any news about that ? or I guess I can work my own f_gets implementation using gfileread()... Or could you also simply open an image using another Fat_fs library (without GFILE), like "fs_open(myImage)", and use the opened file with gdispImageDraw() ? Anyway, great work with uGFX :).
inmarket Posted March 17, 2017 Report Posted March 17, 2017 1. Speed: Yes displays using a SPI interface are not the fastest. If you are talking about image drawing from an sd-card, sd-cards are really slow so your problem could be that rather than the display. Possible solutions might include moving the images to flash (using ROMFS) or caching. Both are compromises in terms of flexibility and/or resource usage. 2. GFILE : Using an additional fatfs library would be a complete waste of ram and flash storage. Implementing a fgets using gfileRead would be trivial in comparison. Also, you might want to look at the stdio emulation option. It might already provide a fgets replacement (I can't remember for sure) but if not fgets is still trivial to implement. Using another file library for image handling is not straight forward. GFILE was originally implemented specifically for image handling. Replacing GFILE for images would not be easy or necessary. GFILE is designed to easily shim other file systems to provide a level of abstraction to file handling.
Grobatt Posted March 22, 2017 Author Report Posted March 22, 2017 Hi, the CC3200 has a built in serial Flash used for application images and network processor, but it can also store user files and it is accessible with TI simplelink API only. If I store my images on this SFlash instead of the SD Card, would it be possible to open them using the TI simplelink API and then use the gDISP API ?
inmarket Posted March 23, 2017 Report Posted March 23, 2017 You will need to create a GFILE wrapper for the ti file api calls. This is very easy using the GFILE_NEED_USERFS configuration option and then defining the wrapper code as part of your project. The api documentation on the uGFX website contains all the detail and the standard GFILE code provides plenty of examples.
Joel Bodenmann Posted March 24, 2017 Report Posted March 24, 2017 And of course don't hesitate to ask if you have any questions - we're happy to help wherever we can
Grobatt Posted March 29, 2017 Author Report Posted March 29, 2017 On 23/03/2017 at 15:32, inmarket said: You will need to create a GFILE wrapper for the ti file api calls. This is very easy using the GFILE_NEED_USERFS configuration option and then defining the wrapper code as part of your project. Thanks for the info ! I'll look into this.
Joel Bodenmann Posted March 29, 2017 Report Posted March 29, 2017 Looking forward hearing about your progress. Don't hesitate to ask if you have any questions!
Grobatt Posted April 7, 2017 Author Report Posted April 7, 2017 Hello I was able to create the needed wrapper to open and read images with uGFX from the SFLASH of the CC3200... sadly it's even slower than with my SD Card. Here is some explanation from TI: How read command from Sflash works: - you send sl_ API command from your code in application processor - command is transferred by 20MHz into NWP (network processor) - NWP read data from sFlash via 20MHz SPI - NWP send data back via 20MHz SPI into your application processor When you read data from sFlash, your data comes via two SPI interfaces. Quite a pity imho that the file API pass through the NWP... well.. So I guess I'll stick to my SD Card or maybe work with an external SPI flash memory. Thanks for your help anyway :).
Jim Posted April 7, 2017 Report Posted April 7, 2017 (edited) @Grobat I don't know if your CC3200 has EMIF (I think it's correct to say only the higher pin count MCU's have the External Memory Interface), if not then of course it will have N2HET(s). Together with Parallel Flash, cheaply available from Digikey etc al (EG this one. Hundreds variations available) ought to do the trick? Indeed, you could just use SRAM. I don't know how many of these images you have to have on hand but you'd be fitting in ~7 per meg. Run Length Encoding (RLE) ought to be quite good increasing that number. Digikey again have choices for Parallel SRAM (x8 TSOP packages probably a good place to start). Good luck! Edited April 7, 2017 by Jim
Jim Posted April 7, 2017 Report Posted April 7, 2017 Additional: And of course you can use DMA & N2HET (or EMIF) to stream directly from Flash/SRAM -> Display (even better if your display is Parallel... but you may be running out of pins with low end CC3200's I suppose).
Jim Posted April 7, 2017 Report Posted April 7, 2017 Ok, ignore my posts. I've not used CC3200 and just assumed it was not too dissimilar to the other TI MCU's but it seems the CC3200 MCU's don't have N2HET, EMIF or any real flavour of HET as it's really cut down for specific purposes... looks nice for some jobs though. Still, you could use parallel Flash just about I think depending what you're doing with what pins are available.
inmarket Posted April 7, 2017 Report Posted April 7, 2017 Can you please post your GFILE ti wrapper code and we will look to add it as an official wrapper in the repository.
Joel Bodenmann Posted April 7, 2017 Report Posted April 7, 2017 What keeps you from simply using ROMFS to load the images from your microcontroller's flash?
Grobatt Posted April 11, 2017 Author Report Posted April 11, 2017 Hi Guys, Sadly i'm already out of pins, I use SPI, I2C, UART, and a few GPIO and PWM... not enough room for a parallel flash ;).. CC3200 has quite a low pin count, maybe I'm playing with its limitations hehe. Basically I wanted to use the WIFI and it's very effective for this but might be a bit small if you have a lot of peripherals. About ROMFS, that's an option I will explore, as well as 'dynamic lib loader' feature of the CC3200, that may be usefull to load images into the RAM only when needed. But from now I'll continue other parts of this project and then get back to the display part later as at this time it works from the SD card, speeding up the display will be andupgrade when everything else works fine :). Thanks
Joel Bodenmann Posted April 13, 2017 Report Posted April 13, 2017 On 4/11/2017 at 18:58, Grobatt said: About ROMFS, that's an option I will explore, as well as 'dynamic lib loader' feature of the CC3200, that may be usefull to load images into the RAM only when needed. No need to load images into RAM at any time. The image simply needs to be in a (fully) addressable memory. If that is the case, µGFX can handle the rest via GFILE. So using ROMFS to store your images in the microcontrollers FLASH means that you can simply render directly out of that.
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now