Jump to content

inmarket

Moderators
  • Posts

    1,295
  • Joined

  • Last visited

  • Days Won

    4

Everything posted by inmarket

  1. One more thought... As a dial device it would be useful to be able to set the range of the dial. Changing the range would have the effect of changing the sensitivity. Eg a dial with a range of 0 to 30 would appear to reach full scale much faster than a dial of range 0 to 300. Alternatively the increment could be changed to change the sensitvity rather than the range.
  2. Rotary encoders was one of things I was thinking about when designing dial. In practice there are two models of use for rotary encoders 1. Like an analogue control eg a volume control. For this model a dial works perfectly. 2. As a direction encoder. For this the toggle interface is the best model with up and down toggles. There is no reason that the driver for the rotary encoder cannot implement both driver interfaces at the same time allowing the user interface to pick which model it wants depending on the context of use. It may even use one model in one location and the other model somewhere else with the one rotary dial. For the centre press a toggle is definitely the correct control.
  3. It was one of those to - do things. The problems you were having just made now the time to do it. I am much happier with the code now. Thanks for your diagnostics and help in identifying problems.
  4. I have largely rewritten gevent. As you surmised the problem was the re-entrancy within the event callback handler that the frame window was doing. Looking at the code it should have never been allowed with the existing implementation. The updated implementation should have none of those issues. It also now completely avoids the use of gfxSemCounter() which is algorithmically nasty anyway (it is also hard to implement on some o/s's eg Win32). I have done basic testing using the frame and widgets demo however I would appreciate you testing the new implementation with your code which appears to test this far more thoroughly than our simple tests.
  5. That is great debugging! Multi-threading issues can be such a pain. I will look very closely at it in the next few hours (just got to time it around real paying work). Thank you for your work in this area. I think the reason this has gone undetected for so long is because in the past listeners have never been created and destroyed continually. They were typically set up once and never destroyed (like the main application listener). I will make sure we get this fixed asap.
  6. Thanks. I will look in detail at that in the morning.
  7. This has been integrated into the repository. I have changed the names a little to be more consistent with other uGFX names and added support for returning the tag in each widget that create events. Thanks for this, it has been a good addition.
  8. Thank-you for this fantastic work. It has been added to the repository.
  9. I have uploaded into the repository a couple of fixes to raw32.h which should help prevent type definition conflicts with standard headers. Hope this helps.
  10. I have looked at the code in question. Your fix in frame.c is definitely required when there are no buttons on the frame window. Thanks for finding it. The change to event.c is NOT required (only the psl->listener field is checked to test for slot availability) and may have other side effects. I have updated the repository with this change. Can you please test if this solves your problem?
  11. There is a test program specifically designed to test mouse drivers. Try starting with that. It is in the tools/touch_driver_test directory.
  12. You are certainly right about window objects taking memory. Unfortunately that is the cost of adding that level of abstraction. uGFX is a LOT better than most other embedded window systems but we are working to make it better yet. We have an internal spreadsheet that we use for tracking memory usage of widgets etc for the purpose of driving our optimisation efforts. We are not ready to release that publicly yet however if you send me a private email I will send it to you. The frame window is particularly bad because it contains a number of "sub-widgets" for the close buttons etc plus special listening code to handle that. Listeners in particular are expensive as under the current model every listener contains a maximum sized event buffer. The way to optimise the frame window is to remove the sub-widgets and have the frame window code do the drawing itself for those objects. This has a number of advantages... It removes the memory requirements for each of the sub-widgets It removes the memory requirements for the special listening code Window move and resize should work correctly as there are no children outside the client area Simplifies object destruction and other code There is however more complexity in the frame window drawing code and it will take time to code. Hopefully soon I will fix it.
  13. The other way (and probably the best way) is to create a generic GWindow object and use the gwin drawing calls to draw on that window rather than the gdisp drawing calls. THe gwin drawing calls ensure that the redraw state is up to date before they perform the actual draw. eg gdispDrawPixel() gets replaced with gwinDrawPixel(). Sorry for the delay in this comment - I wanted to check the code first.
  14. The other thing that will be nice to add is support for a "model" window. It would make your popup window code so much easier. Ahh, so much to do
  15. Redraw in most cases occurs on a timer thread which is why you are seeing the behaviour you mention. This by design to keep certain actions particularly quick. There are some defines which control that behaviour one of which I am sure does all the redraw in a synchronous manner. There are other side effects of using those defines so read the doc on them carefully (or just try them and see what happens). The solution you have used is actually a good solution and shouldn't create any additional redrawing - just change when they happen.
  16. This is code that has been fairly well tested but there are always opportunities for things to slip through. I will have a good look tomorrow. Thanks for bringing it to my attention. PS. The frame window is not an implementation I am very happy with as a) it uses a lot of memory, and b) the window move logic won't work properly because it has children windows outside the client area. These things really require a rewrite of the frame window but that can come later when I have more time.
  17. I will integrate this over the next few days. Thanks.
  18. Thanks. I look forward to going through the code over the next few days and integrating it into the ugfx repository.
  19. Another thing to test us to make sure you have "." at the beginning of your include path. The current directory should always be searched first for an include file but some compilers don't follow the rules. For those compilers "." (without the quotes) must be the first include path to operate in the c standard manner.
  20. Please send me your main.c. There must also be other header files that are conflicting with the type definitions. Seeing your main.c will enable me to check the other header files. Note with ugfx you typically don't need to include any standard header files as ugfx takes care of all that for you when you include gfx.h. You then add standard header files only for stuff the ugfx does not handle. The error log should show which is the conflicting header file and you take the same approach that we took to resolve the stdint conflicts.
  21. The problem is that the int32_t definitions in your system are conflicting with the defintions in uGFX. There are two possible solutions to this... 1. Restore the definitions in raw32.h to what they were and remove the inclusion of in your project. uGFX should then define those types for you and there will be no conflict. 2. Include within the raw32.h file (somewhere around line 27 would make sense (just after the #if GFX_USE_OS_RAW32). Then comment out the definitions for int8_t through to uint32_t (lines 45 - 50) in raw32.h Option 1 is the better solution. If you post a copy of your stdint.h (each compiler uses slightly different definitions) I will try to add protection around the definitions to solve the problem in future where someone includes both files.
  22. Porting should be very easy. Use the frame buffer driver. You only have to supply the board file. That file contains two functions. The first just needs to initialize the hardware and set the frame buffer pointer and size into a structure. The second function is optional and only needs code if the frame buffer needs a sync call. There is a template in the frame buffer driver directory that you can copy and rename. Any help you need just ask.
  23. GREGISTRY it is then. Saving the error silently in a variable for debugger or logging use later sound acceptable to me in order to simplify the api. Ordering from the top for system ones sounds fine. Or just use 0x7FFF for top user. The top bit then indicates a system or user tag. I think you are right - 256 makes a good maximum data size so unit 16 it is. I think that that is probably a good enough first api design. Have fun implementing it. I am looking forward to seeing it. Just for your info - we have just completed work on fat file system support for GFILE. It is currently in a branch and should be merged with the master sometime tonight after final testing. The block interface is currently only written for Chibios but it would be simple to add replacement routines for other os.
  24. THis is turning into a module in its own right. Excellent! What do you think of GREGISTRY or GCONFIG as the module name? I will use the GREGISTRY terminology below just for simplicity in the discussion. As GFILE is light (it is not a full file-system just a shim layer) it makes sense to have GFILE able to access the raw devices as just a block of raw data/memory/device and then use GFILE to implement GREGISTRY. It gives a lot of flexibility to the implementation. A uint16 tag identifier sounds great. I would suggest tags > GREGISTRY_MAX_USER_TAG be reserved for ugfx. That way the user can number their own blocks starting from 0 (nicer for the application). Using a null pointer on the read call to get the size certainly works. More complicated from an API perspective but it seems to be the way most os's do that sort of thing. It is less obvious though. I personally have a pet hate for "errno" style of error reporting (where the error is saved in a global variable). It is not thread-safe and it is non-obvious. I personally also am not keen on passing by ref to get what is effectively a return value. I realise that conflicts with the above statement but that is just my particular design style. Of the two I am more opposed to the "errno" system. I am wondering however for an embedded registry if it really matters why the read or write failed. It is good enough to know that it did and that you didn't get the setting you wanted. Debugging the system will have long ago told you of any systemic problem. For an embedded system fall-back in this type of situation really doesn't need to know why it failed, simply that it did. Using this embedded system simplification we can then can simplify the API... So (as a suggestion): bool_t gregistryWrite(uint16_t tag, const void *data, uint8_t size); uint8_t gregistryRead(uint16_t tag, void *data, uint8_t size); uint8_t gregistrySize(uint16_t tag); Note that use of uint8_t. I am thinking that registry data should always be small. Is 255 bytes a reasonable limit or should this be a uint16_t with a GREGSITRY_MAX_DATA_SIZE #define? What do you think?
  25. One more comment. Specifically about the read call: It is important to be able to determine the size of the buffer needed for the call. Their perhaps needs to be a call to return the size of the buffer needed for the read. As the write could save different sizes even for the one device type, the size of the data block written needs to be saved with the data itself. The read call should probably therefore fail if the data block passed in is not large enough. It may be worthwhile for the read to return the size of the data actually returned with 0 indicating a failure.
×
×
  • Create New...