|
Post by jamesbowman on Aug 6, 2020 13:00:44 GMT -8
Correct. Each character in the string given to cmd_text() is a display list entry. So at a maximum around 2000 characters can be drawn on the screen at the same time. There's also some overhead for each cmd_text(), and for anything else on the screen, so an exact number is difficult to compute. But in practice this limitation is rarely hit, because 2000 characters is a lot. If there is some way of limiting the amount of text on-screen? Or if you're drawing a *lot* of text, it might be better to use a single bitmap with format TEXTVGA. This is a format where every character is a byte in graphics memory. It's what TermDriver uses: excamera.com/sphinx/termdriver/index.html
|
|
janb
Full Member
Retiree, born 1948, mostly HW/FW oriented programming for > 50 years, 25+ for IBM
Posts: 33
|
Post by janb on Aug 7, 2020 3:15:25 GMT -8
James, again I missed your reply; it came on the 'Next Page'... Thanks for your explanation, I guess it all makes sense. As I said above (last addition), a 'GD.finish()' before EACH 'GD.cmd_text()' seem to avoid 'Coprocessor exception's... I'm an "oldfashioned" programmer. I began working for IBM Sweden 1970 as an admin programmer, but switched to technical programming, i.e microcontrollers, end of the 70's, developing test equipments in an IBM plant environment. When the IBM PC arrived, it became both my working tool and the "environment" for my test equipment applications, with a terminal always available (input & output). I still code this way; with input cmds (or "dynamic" cmd buttons), long (or short) "replies", and during development, debugging code (both input & output). As can be seen below, I have several "log lines" on the top rows and a few cmd buttons on the bottom row: a 'Chg' button for various display modes and then 4 buttons to scroll the "log lines" 'L'eft & 'R'ight (horizontally) and 'B'ack & 'F'orth (vertically). Here's my simple WeatherStation setup: I've cut a hole in the lid of the box to make the GD3X flat and intend to use a little glue to keep it in place. What's "a single bitmap with format TEXTVGA"? How can it be used with the GD3X? I'm a novice regarding pixels, bitmaps, fonts & "such"! I'd love to use a monospaced font, since I list values with headings and they look much better via the Serial IDE; I could then also calculate correct line lengths...
|
|
janb
Full Member
Retiree, born 1948, mostly HW/FW oriented programming for > 50 years, 25+ for IBM
Posts: 33
|
Post by janb on Aug 7, 2020 5:32:22 GMT -8
James, as I said earlier, I'd love to be able to handle 'Coprocessor exception's... Is it possible? Can I "catch" such an exception and then perform a correct Reset of the Coprocessor, to be able to restart/continue w/o "human intervention" (= Power Off/On)?
Maybe some sort of 'Watchdog timer' "scheme"? I have very little 'Watchdog timer' experience, but I'm eager to learn... I always want to create ROBUST code, that won't "hang" or otherwise "misbehave"!
My Weather Station application will run for weeks/months unattended at our summerhouse. I don't want to come here after two months, finding that it stopped/"hung" after TWO days, due to "bad coding"!
I suppose it would be possible to implement a wifi connection somehow, to be able to connect/control via Internet, but this would be an even higher hurdle for me to overcome...
|
|
janb
Full Member
Retiree, born 1948, mostly HW/FW oriented programming for > 50 years, 25+ for IBM
Posts: 33
|
Post by janb on Aug 7, 2020 7:26:42 GMT -8
Amazing; I've put 'GD.finish()'-stmts before virtually every other GD-stmt in my code; the 'Coprocessor exception's still occur!
|
|
wawa
Junior Member
Posts: 24
|
Post by wawa on Aug 7, 2020 8:18:01 GMT -8
Back about the jpg problems, I tested it and have the following problem: If "healsky3.jpg" is loaded right after "gita.jpg" the top of the image is lost. If "healsky3.jpg" is not loaded/displayed, "gita.jpg" is fully normal.
void setup(){ GD.BitmapHandle(0); GD.cmd_loadimage(0,0); GD.load("gita.jpg"); GD.BitmapHandle(1); GD.cmd_loadimage(1,0); GD.load("healsky3.jpg"); }
void loop(){ GD.Clear(); GD.Begin(BITMAPS); GD.Vertex2ii(0,0,0); GD.Vertex2ii(0,0,1); GD.swap(); }
|
|
|
Post by jamesbowman on Aug 7, 2020 8:30:37 GMT -8
void setup(){ GD.BitmapHandle(0); GD.cmd_loadimage(0,0); GD.load("gita.jpg"); GD.BitmapHandle(1); GD.cmd_loadimage(-1,0); GD.load("healsky3.jpg"); }
void loop(){ GD.Clear(); GD.Begin(BITMAPS); GD.Vertex2ii(0,0,0); GD.Vertex2ii(0,0,1); GD.swap(); }
The healsky.jpg image is being loaded on top of the gita.jpg image data.
If you use the "-1" argument to cmd_loadimage() then the data will be appended *after* gita.jpg, avoiding the clobbering.
|
|
wawa
Junior Member
Posts: 24
|
Post by wawa on Aug 7, 2020 8:37:53 GMT -8
I thought it was a memory limitation of the UNO. I misunderstood handle and pointer in your functions. Thanks!
|
|
wawa
Junior Member
Posts: 24
|
Post by wawa on Aug 7, 2020 23:40:56 GMT -8
By the way, if you don't use -1, how do you calculate the pointer value to store the next image? Also, how many images of 480x272 can you preload in memory?
|
|
janb
Full Member
Retiree, born 1948, mostly HW/FW oriented programming for > 50 years, 25+ for IBM
Posts: 33
|
Post by janb on Aug 8, 2020 10:00:02 GMT -8
I've implemented a Watchdog-Timer concept in my code, but it can't restart the GD3X; it needs PowerOff/On (both the external Net Adapter & the USB Serial connection)! 'GD.begin(...)' hangs after Reset, meaning that the Watchdog-Timer restarts over and over again (5 seconds in between)... I even tried to do a successful 'GD.reset()' BEFORE the Watchdog-Timer restarts my code, but the 'GD.begin(...)' hangs anyway!
I even tried to modify 'GD.reset()' in the GD2.cpp program, to do as described in the FT800 Programmers Guide, under 5.5 Fault Scenarios: 1) If I do a 'GD.reset()' during normal circumstances, it runs ok, the GD3X seems ok and my program continues...
2) If I "force" a Watchdog-timeout and my code is restarted, and then, during setup, before 'GD.begin()', execute a 'GD.reset()', it too hangs!
|
|
|
Post by jamesbowman on Aug 8, 2020 13:52:39 GMT -8
wawa the -1 value appends the image after the last image. Because it sets up all the bitmap registers, you don't actually need the address. Of course if you know the image dimensions you can compute fixed addresses anyway. 480*272*2 = 261120, so you can fit 4 in 1Mbyte. janb maybe a more fruitful approach would be for you to post a test case that shows the crash? Then we can take a look at finding the root cause. From the screenshot it looks like the text should not overflow the display list.
|
|
janb
Full Member
Retiree, born 1948, mostly HW/FW oriented programming for > 50 years, 25+ for IBM
Posts: 33
|
Post by janb on Aug 8, 2020 15:21:09 GMT -8
James, I'm sorry, but I'm not able to create a 'Coprocessor exception' under controlled circumstances. It (only?) happens, when I'm using the 'L'/'R'-buttons to shuffle long text lines back & forth horizontally. It does NOT seem to happen if I don't touch the screen, even though I POLL the screen code about 40 times per second.
A new text line is added to a circular buffer every quarter of an hour, several/many text lines can be added if I execute commands, either via the Serial Monitor or via the keyboard / cmd buttons on my GD3X screen.
Sooo, I probably wouldn't have any problems, leaving the application unattended for weeks/months...!?
BUT, my main concern now is, that I REALLY would like to find a way to regain control after a 'Coprocessor exception', so that I could restart, w/o having to do Power Off/On!
Look also at my previous post above; I've added more text about my recent Watchdog-trials to it...
|
|
janb
Full Member
Retiree, born 1948, mostly HW/FW oriented programming for > 50 years, 25+ for IBM
Posts: 33
|
Post by janb on Aug 16, 2020 3:19:26 GMT -8
James, latest findings... I have extracted all code regarding the LCD Screen (GD3X) from my (rather big) WeatherStation program and created a "standalone" program, with its own setup() & loop() code calling my LCD Screen code. With this setup, I don't seem to have any problems with sudden "hangs", as long as I have the extra, external power, ON. My Laptop's USB Port power isn't enough to drive the GD3X.
BUT, I still have problems with the 'GD.begin(...)'! Every time I make a change to my code, recompile and upload it, the new version "hangs" on the 'GD.begin(...)' stmt! I then have to switch OFF the external power, unplug the USB cable, switch ON external power and re-plug the USB cable. Then, most of the times, the new version of my program starts & runs successfully! This is a real "pain"; the USB cable connector & the Laptop's USB Port Connector actually are "wearing out"!
BUT, I have found a "remedy" for this! There's a 'GD.reset()' cmd defined in 'GD2.h' & 'GD2.cpp'. If I use it "asis", it doesn't help... BUT, if I add TWO lines to the 'GD.reset()' code, as described in the FT800 Programmers Guide, under 5.5 Fault Scenarios, the 'GD.reset()' cmd seem to help. Whenever I want to modify my program code: - I first execute the modified 'GD.reset()' cmd in the currently running program AND stop using GD3X cmds - I then modify, recompile, upload & run the new version - It contains the 'GD.begin(...)' as the first cmd to the GD3X, and then continues executing normally...
Usually, this modified 'GD.reset()' cmd helps, so that I don't have to perform the power OFF/ON and un-plug/re-plug of USB cable...!
Below is my modified 'GD.reset()' cmd in 'GD2.cpp':
void GDClass::reset() { GDTR.__end(); GDTR.wr(REG_CPURESET, 1); GDTR.wr(REG_CMD_READ, 0); //JBn GDTR.wr(REG_CMD_WRITE,0); //JBn GDTR.wr(REG_CPURESET, 0); GDTR.resume(); }
Unfortunately this updated 'GD.reset()' cmd doesn't help with the "Bluescreen" 'Coprocessor Exception Error' on the GD3X. If I have the WatchDog "active" in my WeatherStation program, it "traps" the "hang" after the Error and restarts my program. BUT, either 'GD.reset()' or 'GD.begin(...)' during this program-restart will then "hang"; Power OFF/ON of GD3X & Teensy is needed!
|
|
wawa
Junior Member
Posts: 24
|
Post by wawa on Aug 16, 2020 21:30:26 GMT -8
I don't know if it can help, but it's famous that for some Arduino boards you need a capacitor between the ground and reset pins. It is used in the case you need to press the reset button to start the code after the board is plugged. With this capacitor, you don't need to press the reset button anymore.
|
|
janb
Full Member
Retiree, born 1948, mostly HW/FW oriented programming for > 50 years, 25+ for IBM
Posts: 33
|
Post by janb on Aug 18, 2020 0:22:42 GMT -8
Unfortunately a capacitor won't help with my RESET problems...
Electrical stuff/design is beyond my skills; I'm strictly a SW/FW guy! I can use jumper wires on a breadboard; that's about it!
I'm using a Teensy 3.5 board and it too has a Reset BUTTON plus a Reset PIN. But the Teensy normally resets/restarts when a new program is loaded via the USB cable...
Arduino Uno boards have a Reset PIN and even though the GD3X pinout is made for Arduino connections, the Reset PIN is left out! The documentation doesn't mention a 'GD.reset()' cmd, but the GPU's (FT800) Programmers Guide describes this cmd and it's also defined in the GD2.cpp/GD2.h code. BUT, this 'GD.reset()' cmd can HANG; it never returns control!
Also, it doesn't help to only Power OFF/ON the GD3X; the Teensy's USB connection cable must be unplugged too. It seems as if the GD3X also is "powered" via the other i/o pins in the setup...!
|
|