Jump to content

steved

Members
  • Posts

    64
  • Joined

  • Last visited

Everything posted by steved

  1. I'm implementing a pop-up window, in a similar manner to that described at http://wiki.ugfx.org/index.php?title=Frame#Overlay. Using chibios (V3 SVN) I get a semaphore-related system crash during destruction of the popup, which appears to be triggered within the event handler. Not managed to pin it down yet, but it looks as if maybe the event listener created by the popup window isn't getting fully destroyed. Code crashes on line 156 of gevent.c: gfxSemWait(&psl->pListener->eventlock, TIME_INFINITE); // Obtain a lock on the listener event buffer The create and destroy code all runs on the main ugfx event handler loop. To create the popup: gwinSetEnabled(ghFrameScreen, FALSE); // Disable main screen - all elements are in a container ghFramePopup = createKeypadDisplay(0, "Access Code"); // Add some buttons in a frame To destroy the popup, and reinstate the main screen (in response to a button press on the popup): gwinDestroy(ghFramePopup); ghFramePopup = NULL; gwinSetEnabled(ghFrameScreen, TRUE); The call stack is as follows: gfxSemWait() (chibios.c:121) geventRegisterCallback() (gevent.c:129) _frameDestroy() (frame.c:42) gwinDestroy() (gwin.c:175) At one point the crash didn't occur until the first button press on the main screen (after the popup was destroyed). I added a line of code after line 44 in gevent.c: 44: psl->pListener = 0; 45: psl->pSource = 0; // Added as experiment At the time that appeared to make a difference; then the problem returned. I'm still trying to thread my way through the event code Has anyone else experienced something like this?
  2. I've added an option to widgets to assign a 'tag' value (as is done in Delphi) which can greatly simplify event handling - overall it may well save both RAM and code space in some applications - no need to do lots of comparisons with widget pointers. For example, a keypad can assign tags which convert readily to ASCII characters, permitting use of generic decoding routines. The notes in the attached files give an example. Very simple addition. event_handling_using_tags.zip
  3. Following on from my previous post, I've written some code for a general-purpose registry for small chunks of data; generally as the discussions in that thread. Not properly integrated into ugfx, but works for me! I'm using the code on ChibiOS with a small I2C FRAM (similar to an EEPROM) - limiting data size to about 250 bytes for simplicity at the I2C level. There's also a skeleton interface to GFILE. Each registry entry is assigned a 'tag' (16-bit value), with two ways of using the code: a) With a list of predetermined tags. (Very small code overhead) b) More as a crude (but simple) file system, where any tag value is allowed. The code also introduces another idea - a set of ugfx-wide error/result codes, which may generate some comment! ugfx_updates_010714.zip
  4. I agree - the term 'Registry' seemed to describe the function of the module well, so having a different name for the module and its entry points then seems perverse.
  5. GREGISTRY sounds the best choice to me Once the API is defined, it shouldn't matter whether GFILE is used or not; obviously helpful to some if there is a GFIL-based implementation. (My own applications may well want to manage NVR themselves, rather than letting GFILE do it). Sounds reasonable. To avoid losing registry data if GREGISTRY_MAX_USER_TAG is redefined during a code upgrade, I'd then assign uGfx tags growing down from GREGISTRY_MAX_TAG_VALUE (which will be 65535) - as with stack and heap. It's a refinement which should be simple to implement; as I envisage the use of this module, most callers will already know the size or maximum size of the data. And if returning a 'buffer too small' error in response to a normal read, we could return the actual size of the data (discussion point - its a somewhat inconsistent return). Me too. At the most basic level, you are absolutely right. However, I have found from experience that logging the more detailed error code can help diagnose any subsequent problems - on low-volume systems debugging rarely covers all possible use cases (and sometimes, regardless of the amount of debugging/testing, coding errors can lurk undetected for years!). The logging need not be complex; a simple memory location which holds the last error encountered can be sufficient. And using a large number of different error codes can help home in on precisely where an error occurred. (Consider reading back data - a 'buffer too small' error will require different remedial action to 'storage device failure'). I considered the same question, and concluded that a reasonable limit is actually 256 bytes! Its a much more useful size than 255. So unless we have a special case of zero really meaning 256 (ugh) we need uint16_t with GREGISTRY_MAX_DATA_SIZE.
  6. I'd see GFILE as an option, rather than the only solution - for myself, initial implementation will write calibration and other information to non-volatile memory, without a file system in sight. This is probably typical of many embedded systems, which don't need the complexity/code space of a file system (even if someone's already solved the problem!). Although if its easy to point GFILE at an block of non-volatile memory.... (I use a small FRAM, communicating over I2C, since speed isn't at all important for small blocks of data. Each data block includes a size and a checksum). Keeping the general principle of ugfx, maybe we support GFILE and various direct memory-based arrangements using drivers. The various comments seem to be building on the principle quite nicely: 1. We call it a 'registry' - so my data identifier becomes some sort of tag. We could leave the tag as a unit8_t, or extend it to uint16_t to give more flexibility. Split the tag's number space into two blocks; one for ugfx-related devices (first 64 tags, say), and one for user tags. It's then up to the registry driver how to assign a storage location; a simple non-volatile memory driver might have a table relating tags to start addresses, while a file system might create a file name based on the tag. 2. A separate 'get data size' call seems sensible for those situations where the data size is variable. Some (most?) uses will have a fixed or known maximum data size, and not need to use this call. 3. The read routine would certainly need to check that its not going to overflow the passed buffer. If we pass the buffer size by reference, it can then be filled in with the actual size of the data block on return, and either a 'success' return code or a 'buffer too small' error code. (I don't think we want to get into passing data in chunks - that's surely a case for direct file system access. I would expect registry entries to be quite small.) So the API becomes three entries: gfxError_t gfxSaveRegistryData(uint16_t tag, const uint8_t *data, uint16_t dataSize); gfxError_t gfxReadRegistryData(uint16_t tag, uint8_t *data, uint16_t *dataSize); gfxError_t gfxReadRegistrySize(uint16_t tag, uint16_t *dataSize); I've deliberately adopted the format for gfxReadRegistrySize() for consistency and helpfulness; it gives the opportunity to return error codes for 'invalid tag' and maybe 'no data stored', which is less ambiguous than simply returning zero for both these cases. Edit: As an alternative to gfxReadRegistrySize(), if gfxReadRegistryData() accepts a null pointer for the data buffer, it could just return the data size.
  7. Unless I get deflected, I shall probably code this up myself, next week. Mostly want to be comfortable that the API is sensible and practical. (I've already got another potential use, supporting a number of resolution-compatible displays. It could also be a way of supporting a number of different resolutions).
  8. Some LCDs take a bit of time after reset to initialise (I have one that needs a second) - maybe a power up delay. Web site for the board was down, so couldn't check.
  9. I've been looking at loading and saving touch screen calibration data, and making the interface more generic. It comes down to streams of bytes, so the same interface could be used with displays and other I/O devices as general configuration data (e.g. setting a display type or resolution) I propose the following interface: gfxError_t gfxSaveDeviceConfig(uint8_t deviceID, const uint8_t *data, uint16_t dataSize); gfxError_t gfxReadDeviceConfig(uint8_t deviceID, uint8_t *data, uint16_t dataSize); gfxError_t is a result/error code type whose values are to be determined (also on the TODO list); with codes for success, possibly 'not implemented', and various reasons for failure. The caller can then take action (or ignore) as is appropriate - for example on failing to read touch screen calibration data, the calibration screen is displayed. The underlying routines can then access whatever non-volatile store is available, and possibly even provide sensible defaults in some cases. deviceID needs defining in some way, so that it can reliably reference input devices, displays and so on. Maybe a simple block of values for each device type; for example: 0x00..0x07 - touchscreens 0x08..0x0f - dials 0x80..0x83 - displays Any comments?
  10. steved

    Processor power?

    Just the sort of constructive response I was hoping for, thankyou. Low volume project, so STM32F407 it will be.
  11. Bit of an open-ended question here - I'm trying to get a feel for how much processing power I'll need to provide a responsive display using uGFX. Looking at the Displaytech INT070ATFT-TS, which is a 800x480 display with touch screen, using the SSD1963 controller and MAX11802 touch screen interface. The graphics side is pretty undemanding - mostly simple coloured boxes with text in them - no images and no animation, and little user interaction. Main need for responsiveness comes when the user is entering configuration data, which I envisage being a selection of the elements supported by GWIN - radio buttons, checkboxes, lists and some numeric entry, with data entry solely by touch screen. The processor will be doing very little apart from servicing the display - a modest amount of I2C comms and that's all. I've used the ST 32F051 with ChibiOS on another project, so that processor, or if necessary a more powerful one from the 32F family, is the favoured choice provided its likely to be adequate. Can anyone give any advice based on practical experience? Thanks
×
×
  • Create New...