Adafruit touchscreen (AR1100)
Chris Mahoney (1684) 2165 posts |
Do you ever sleep? :) Thanks for that. It might be another couple of days before I get a chance to try it, but it certainly looks promising. In the meantime, here is my very quick and dirty “pointer test” app that shows the current coordinates, in case anyone’s interested or wants to test their own touchscreen. It works with an unmodified ROM. |
Chris Mahoney (1684) 2165 posts |
Well the good news is that that code appears to work, unmodified :) I’m having trouble with getting the very top/bottom of the screen to work, but that might be the screen itself. I’l retest it on my Mac when I get a chance (hopefully later today). I wasn’t able to get it working without hard-coding 4096 in there (but I haven’t given it much of a try yet) so it’s not yet “portable”, but I’ll take a look at that when I get a chance too. Perhaps the NetBSD code holds the answer… |
Jon Abbott (1421) 2641 posts |
My screen turned up yesterday, so I’ll be catching you up soon. Now that I’ve starting looking at it, I’ve realised the TRM doesn’t cover the touch side of it, so have just eMailed Tontec for assistance. I’m thinking about how to best code a Touchscreen PointerV Module, so it’s generic and not specific to the Touchscreen I have. Only problem being the interfaces differ, yours is USB, mine is via SPI so an API may be required. What parameters will it require?
Anything else? |
Chris Mahoney (1684) 2165 posts |
It really only needs min and max because the scaling can be calculated from the resolution. There must be a way to query the min/max though, just need to figure out how. |
Chris Mahoney (1684) 2165 posts |
It’s not working under OS X either, so I can’t blame RISC OS for that! :)
It does indeed seem from the NetBSD source that sc→sc_loc_x and sc→sc_loc_y should help, but I haven’t had this working yet. I’ll keep experimenting when I have time. |
Jon Abbott (1421) 2641 posts |
Could you do it automatically and just increase your max limit as it sees values go over the existing max you’ve seen? I quick drag across the screen should then calibrate it. |
Chris Mahoney (1684) 2165 posts |
That would work :) I expect to have some time tonight so I’ll try to sort it out then. |
Chris Mahoney (1684) 2165 posts |
All working :) if(sc->flags & UMS_ABS) { static int oldx, oldy; static int scalex, scaley; if(dx != oldx || dy != oldy) { oldx = dx; oldy = dy; static const int vduin[5] = {4, 5, 11, 12, -1}; int vduout[5]; _swix(OS_ReadVduVariables, _INR(0,1), vduin, vduout); int width = (vduout[2] + 1) << vduout[0]; int height = (vduout[3] + 1) << vduout[1]; if(dx > scalex) scalex = dx; if(dy > scaley) scaley = dy; dx = dx * width / scalex; dy = height - (dy * height / scaley); _swix(OS_CallAVector, _INR(0,4) | _IN(9), PointerReason_Report, PointerDevice_USB, dx, dy, 0x6f736241, PointerV); } } else if(dx || dy) { _swix(OS_CallAVector, _INR(0,3) | _IN(9), PointerReason_Report, PointerDevice_USB, dx, dy, PointerV); } I’ve moved the OS_ReadVduVariables call down a little further just so that it’s only called when needed. I considered saving the results of it, but that would cause odd behaviour when changing the screen resolution so I decided against it. As for the legal stuff, I don’t know what my rights are around that, but as far as I’m concerned anyone can use the above code freely (or it can be merged into the main CVS if anyone cares to do so). Of course, Jeffrey came up with the bulk of it :) Edit: There’s a potential issue here when “self-calibrating”, namely that this particular screen seems to have trouble with touches at the very top and bottom. That may cause the calibration to go out of whack, returning, say, 3800 instead of 4096 when the top of the screen is touched. Admittedly I only did a quick test before posting that code so I’m not yet sure how much of a problem it is in the real world, but it’s still not as accurate as it could be. The best solution is still to get the actual “4096” values out of the device, which must be possible since OS X can use it without calibration or drivers. |
Jeffrey Lee (213) 6048 posts |
Indeed! I’ve just had a quick through the HID spec, and it looks like the logical minimum & logical maximum descriptors contain what we need (see section 6.2.2.7, and the remarks on pages 36/37). Those remarks concern themselves with converting into physical units (inches, meters, etc.) but judging by some OpenBSD sources it looks like we can just skip out the physical conversion and just scale the min/max values up to the screen size. The relevant OpenBSD sources are here – see the loop at the end of hidms_setup that walks the descriptor and extracts the min & max values. Then there’s the code in hidms_input that does the scaling. It looks like those HID functions should be the same as the ones we’re using (based on NetBSD – I’ve already checked there and they don’t seem to have any obvious touch panel support yet), so it shouldn’t be too hard to port over the required code. It also looks like they’ve got some kind of feedback/calibration coming in from the rest of the OS (see hidms_ioctl) – I’m not sure if that’s just so that it can get told the size of the screen (i.e. pixel width/height to scale the output to), or so that people can manually calibrate their touch panels. |
Colin (478) 2433 posts |
If you want an idea of the format of the hid descriptor the latest version of my USBDescriptors.zip lists the hid descriptor. Hmmm. Unfortunately the link doesn’t work – I’ll have to look into it. |
Steve Pampling (1551) 8154 posts |
Iconbar got broken a few weeks ago, obviously not completely fixed. |
Jon Abbott (1421) 2641 posts |
Colin – attach it to a thread on JASPP Pi forum if you can. I may need to have a look into this as well – still not totally sure how this all hangs together with SPI though, it may or may not be applicable to getting the max values. I’m hoping to start work on it all either later this week or next, I might tackle the touchscreen side of it first as I can control the mouse on the TV using it. It’s probably going to be easier to implement than the GraphicsV driver which requires more planning. |
Colin (478) 2433 posts |
I tried but didn’t get an activation email when I registered. Should I get one immediately?
ftp is working but unfortunately not http. |
Jon Abbott (1421) 2641 posts |
You should have received an email notification, it sent one at any rate. I’ve manually activated the account for you. |
Chris Mahoney (1684) 2165 posts |
Latest update: I have the OpenBSD code compiled, and it works with a regular mouse, but hard-freezes the system when I touch the screen. Baby steps :) I’ll do some more messing around over the long weekend. Edit: It’s a divide by zero error; obviously the detection code isn’t working properly. “Look at Colin’s code” is now on the to-do list! |
Colin Ferris (399) 1809 posts |
Are there any ideas – on how to handle the 3 mouse buttons? |
David Feugey (2125) 2709 posts |
Hardware buttons? :) Hum… Clic for left, long click for menu + on screen modifier for adjust ? |
Raik (463) 2059 posts |
The touchpad on my keyboard do |
Chris Mahoney (1684) 2165 posts |
That’s something that I’ve given a little thought to. For my own purposes I’m going to make apps that work with just the left button, but obviously for full touch support in the OS we’ll need more. We could potentially implement “tap and hold” to do a Menu click*. Adjust will be a little trickier though! *As David said… I should actually read the existing replies first next time :) |
Chris Mahoney (1684) 2165 posts |
I have it working! :) I need to make a couple of tweaks to handle the minimum bounds (which are 0 with my device) but I expect to post all the code here soon. |
Chris Mahoney (1684) 2165 posts |
OK, all changes are to mixed.RiscOS.Sources.HWSupport.USB.NetBSD.build.c.usbmouse, and no other files need to be modified. The first change is a new struct. I put this near the top of the file, just after #define MAX_BUTTONS 31. struct tsscale { int minx, maxx; int miny, maxy; }; Just after that is the struct definition for ums_softc. Add the following line at the end: struct tsscale sc_tsscale; The first block of actual code is in do_attach_mouse and gets the bounds of the touchscreen. I put the following code near the bottom (just before sc→sc_ep_addr = ed→bEndpointAddress;): struct hid_item h; struct hid_data *d; d = hid_start_parse(desc, size, hid_input); while(hid_get_item(d, &h)) { if(h.kind != hid_input || HID_GET_USAGE_PAGE(h.usage) != HUP_GENERIC_DESKTOP) continue; switch(HID_GET_USAGE(h.usage)) { case HUG_X: if(sc->flags & UMS_ABS) { sc->sc_tsscale.minx = h.logical_minimum; sc->sc_tsscale.maxx = h.logical_maximum; } break; case HUG_Y: if(sc->flags & UMS_ABS) { sc->sc_tsscale.miny = h.logical_minimum; sc->sc_tsscale.maxy = h.logical_maximum; } break; } } hid_end_parse(d); Last but not least is the code in ums_intr that actually moves the pointer. As noted on the previous page, this replaces the “if(dx || dy)” stuff. if(sc->flags & UMS_ABS) { static int oldx, oldy; if(dx != oldx || dy != oldy) { oldx = dx; oldy = dy; static const int vduin[5] = {4, 5, 11, 12, -1}; int vduout[5]; _swix(OS_ReadVduVariables, _INR(0,1), vduin, vduout); int width = (vduout[2] + 1) << vduout[0]; int height = (vduout[3] + 1) << vduout[1]; dx = ((dx - sc->sc_tsscale.minx) * width) / (sc->sc_tsscale.maxx - sc->sc_tsscale.minx); dy = height - (((dy - sc->sc_tsscale.miny) * height) / (sc->sc_tsscale.maxy - sc->sc_tsscale.miny)); _swix(OS_CallAVector, _INR(0,4) | _IN(9), PointerReason_Report, PointerDevice_USB, dx, dy, 0x6f736241, PointerV); } } else if(dx || dy) { _swix(OS_CallAVector, _INR(0,3) | _IN(9), PointerReason_Report, PointerDevice_USB, dx, dy, PointerV); } |
Chris Mahoney (1684) 2165 posts |
The code above could be useful to other people, so could someone “in the know” advise how to submit it back to ROOL to potentially get it included in the ROM? The “contact us” page says that “Submissions should ideally be supplied to us in patch form from a known revision of the published sources” but I’ve never submitted this kind of thing before so I don’t know how to make a patch (and Google isn’t being much help). |
Richard Walker (2090) 431 posts |
I don’t know about the RISC OS / DDE side of things, but normally a ‘patch’ is considered to be a text file which, when given to the ‘patch’ utility, will turn version X of a source file into version Y. So it makes the appropriate inserts/deletes. You need to get the file mixed.RiscOS.Sources.HWSupport.USB.NetBSD.build.c.usbmouse from CVS as it is now, and compare that with a ‘diff’ utility to your updated version. Then those differences can be expressed in a ‘patch’ file which can be sent to ROOL. Typically, a diff utility will generate a patch file for you. Sorry if that sounds a bit vague. I have not done such a thing for over ten years, and it was on a Linux system. Not had any recent RISC OS practice! I assume that in the DDE there are equivalents/ports of patch and diff? |
Chris Mahoney (1684) 2165 posts |
There is a “Patch” utility supplied with RISC OS, but as you noted it seems to be for adding existing patches to apps rather than for creating patches. I’m pretty sure that I saw a Diff utility in the DDE so I’ll take a look at that when I get home. Thanks for the tip :) |
Chris Mahoney (1684) 2165 posts |
OK, while Diff exists, it doesn’t seem to save the results in a “machine-readable” format – the output appears to be intended for humans. But I could be wrong! The Patch utility, upon further investigation, doesn’t seem to be a generic patcher and doesn’t appear to take a diff file as input. This should probably be in a new thread, but I’ll bear with it for the moment… Edit: I’ve done it under OS X for now, but it’ll be good to know how to do it in RISC OS for the future. Another Edit: Come to think of it, it’s probably fine to use OS X – doing it in RISC OS means waiting half an hour for the source tree to decompress again to get the latest “clean” file! |