Shop Learn
P2 Hosted USB Keyboard/Mouse - Page 5 — Parallax Forums

P2 Hosted USB Keyboard/Mouse

1235

Comments

  • One thing I'm wondering: Could USB be done without consuming a cog of its own (for example, polling some HIDs inside a video cog during blanking)

  • cgraceycgracey Posts: 13,406

    Or, could it be run over interrupts?

  • RaymanRayman Posts: 11,842
    edited 2021-02-21 00:22

    I think it has to have a cog in order to use interrupts, right?

    I could see it sharing with vga driver with little cog code...

  • I think the core USB transaction mechanism will always need its own cog, as the host must continuously monitor the bus along with the scheduling of bus transactions. It might be doable if it was restricted to low-speed devices only, as they do not require full-speed's 1ms frame that is held to +/- 500ns accuracy. But my gut is telling me a dedicated cog is likely to be in the mix.

    @cgracey said:
    Garryj, at this point in time, do you see any tight spots in doing 12 Mbaud USB, or any ambiguities due to how the smart pin USB hardware works? Is there anything that seems hard to get certain control of? Do you feel like it's possible to do USB perfectly?

    12 Mbaud is looking pretty good, as long as the P2 sysclock is 96MHz or higher.

    I'm still (very slowly) working on a hub-capable version which works with one USB cog. The host is freed from some of the the device connect/disconnect load that is handled by the hub. I have full-speed boot protocol keyboard/mouse working fairly well with up to four ports. Low-speed devices via hub has been a tougher nut to crack, but this is likely due to my inability to grasp what chapter 11 of the USB 1.11 and 2.0 docs are trying to tell me. When a low-speed device is connected to the hub, up-stream traffic is done at full-speed, with low-speed signaling. When the host replies, it does so transmitting a "PRE" packet ID at full-speed, followed by the low-speed data packet(s) transmitted at full-speed, with low-speed signaling. After all data packet(s) have been transmitted, a low-speed EOP terminates the transaction.

    I'm at the stage of getting the full-speed devices a bit more stable, then I will in be in better shape for another look at low-speed devices via hub. Since this (apparently) requires changing the USB NCO on the fly, it could possibly expose something regarding the smart pin USB hardware...

    This Wikipedia page has an example of using the PRE PID:
    https://en.wikipedia.org/wiki/USB_(Communications)#PRE_packet_(tells_hubs_to_temporarily_switch_to_low_speed_mode)

  • cgraceycgracey Posts: 13,406
    edited 2021-02-21 01:12

    Thanks, Garryj.

    If you ever had the time and inclination, It would be very neat to see a Mass-Storage-Class
    setup, so that we could drop files from a host onto what looks like a drive, in order to load the P2.

    Using such a setup to access a file system on the 16 MB flash would be neat, too.

  • roglohrogloh Posts: 2,957

    @Wuerfel_21 said:
    One thing I'm wondering: Could USB be done without consuming a cog of its own (for example, polling some HIDs inside a video cog during blanking)

    Wait, are you now talking about zero total COGs needed for USB? I think there are two parts, the low level time critical bit where one COG manages the transactions, and what I'll call the "polling COG" which can be made part of the application and it just is reading some fifos reporting mouse position and keyboard updates etc. I can see the polling COG being merged into some existing COG that can check/update this automatically in some ISRs etc, but I can't really envisage the time critical COG part being able to run everything entirely in one scan line blanking interval for example, especially if it is now in hub exec instead of cog exec and would subject to more execution timing delay and its timing harder to characterize.

    To me it would seem you'd still need to dedicate one COG per USB physical port. But @garryj could probably answer it definitively. Maybe there is only a very small part that is the critical real time portion during the actual IO transfer, and the short boot protocol polling transfers could complete in ~48 microsecond intervals @ 12Mbps (eg, active video portion for a blank NTSC/PAL scan line) and so it can return in time for the next streamer command. What happens when it's now VGA and the execution time limit shrinks to 25us or less, etc, or if it's only a low speed USB device? I expect there'll be major problems with that approach.

    I think to help save COGs it would be better to try to get USB hub support so a keyboard AND a mouse (and in time perhaps other devices) could all share a single port using a USB hub and therefore only burn a single COG and two pins.

  • uhm, what does it mean when the error led flashes a bit and then the keyboard stops working?

  • evanhevanh Posts: 10,429
    edited 2021-02-22 01:10

    On the Prop2 Eval Board? That'll be USB supply droop detected I suspect. Happens when the Eval Board is overloaded or the programming cable is weak. The USB port will be responding by powering down for its protection ... and requires re-socketed to restore power.
    Also had to be explained to me before I understood.

  • @Wuerfel_21 said:
    uhm, what does it mean when the error led flashes a bit and then the keyboard stops working?

    evanh may have something here. Are you getting your 5v from the PC or AUX connection? The configuration descriptor of the PS2 adapter I'm testing with reports a MaxPower of 400mA, which is 300mA higher than most of the Kbd/Mouse devices I test with.

    I've been able to confirm the no keyboard at initial connect issue, but I haven't yet found a fix. As a work-around, if you connect the PS2 adapter in with the keyboard connected and it does not get recognized, disconnecting the adapter and connecting again usually works. I'm scratching my head a bit as to the root cause, because once it's successfully connected, everything looks very clean.

  • Yep, it was the power being too weak. Now it works perfectly.

    Also, I don't think the PS/2 adapter working / not working has anything to do with Ray's modifications, it's the MiniKbMObjDemo.spin2. That program won't detect it without re-plugging, regardless of which driver variant. Works perfectly fine in the VJET example program (where I never tried the unmodified version due to lack of a keystate method).

  • I also can't get anything to work at all with flexspin, the LED just starts flashing as soon as I press any key.

  • @garryj said:
    Low-speed devices via hub has been a tougher nut to crack, but this is likely due to my inability to grasp what chapter 11 of the USB 1.11 and 2.0 docs are trying to tell me. When a low-speed device is connected to the hub, up-stream traffic is done at full-speed, with low-speed signaling. When the host replies, it does so transmitting a "PRE" packet ID at full-speed, followed by the low-speed data packet(s) transmitted at full-speed, with low-speed signaling. After all data packet(s) have been transmitted, a low-speed EOP terminates the transaction.

    Sounds to me like, given that low-speed signalling has opposite polarity to full-speed signalling, that you're doing 12Mbit timing, but the inverted polarity that low-speed uses.

    So, send a "PRE" packet ID with standard signalling, then the low-speed data packets with inverted signalling, but at full-speed rate.

    Note, that's just my read of the above text. I haven't actually done USB like this.

  • @Circuitsoft said:
    Sounds to me like, given that low-speed signalling has opposite polarity to full-speed signalling, that you're doing 12Mbit timing, but the inverted polarity that low-speed uses.

    So, send a "PRE" packet ID with standard signalling, then the low-speed data packets with inverted signalling, but at full-speed rate.

    Note, that's just my read of the above text. I haven't actually done USB like this.

    That has been my interpretation, so far. Now that I've got full-speed working pretty well via hub, it's time to take another stab at it. Thanks for the feedback!

  • @Wuerfel_21 said:
    I also can't get anything to work at all with flexspin, the LED just starts flashing as soon as I press any key.

    I've reproduced this, but I have no answer yet as to the why.

    My testing so far has been with the MiniKbmObjDemo top file and both Ray's and my USB object code which has been working, though my object sometimes needs the unplug/plug at startup, when compiled with PNut or flexspin. But with Ray's object, PNut works, but flexspin behaves as you described. My USB analyzer hasn't been much help here, because the PS/2 adapter enumeration and configuration data looks good, until you press a keyboard key. My only guess at this time is that some flexspin/PNut difference may be sending the code down an unexpected path...

  • RaymanRayman Posts: 11,842

    I’m using flexspin with this all the time... version 5.0.8 at the moment I think...

  • roglohrogloh Posts: 2,957

    @garryj said:
    My only guess at this time is that some flexspin/PNut difference may be sending the code down an unexpected path...

    Maybe the two tools are generating slightly different binaries for your USB PASM code?

    It might be very tedious/difficult but if you exhaust the other options and get really desperate you might be able to extract the binary portion of your COG code from the flexspin listing file or final binary and compare to the binary output from PNut looking for differences of concern if you suspect it is in COG code. Memory address layout differences between tools will unfortunately cause unwanted differences if hub addresses are embedded within it but maybe you'll find some other key difference that matters. Unfortunately right now I don't see any listing being generated for PropTool which makes things difficult to locate where in the binary the USB code will be situated, can PNut do one?

    Also be sure to check the P2 clock speed and clock mode are exactly the same in both tool's setups.

  • Wuerfel_21Wuerfel_21 Posts: 1,449
    edited 2021-02-24 20:13

    @ersmith @garryj

    I've busted out that manky chiclet DVORAK USB keyboard (yes) and it has a different issue with flexspin. It doesn't err, but the keys only come through sometimes / in batches. Works perfectly fine in PropTool.
    Oddly enough, the keystate query function in my modified version works fine, so it seems it is correctly communicating with the keyboard, just not handling the key buffer correctly

  • ersmithersmith Posts: 4,750

    I wonder if there might be a race condition somewhere, and the PropTool code is slow enough that it never triggers, but flexspin compiled code makes it happen?

  • ersmithersmith Posts: 4,750

    Ah, I think I see the issue -- fastspin arranges variables in the VAR block to pack them efficiently (and optimize memory accesses), just like Spin1 does. Whereas Spin2 does not re-order any of them.

    For now the work-around is probably to put the parameter block passed to the COG in a DAT instead of in VAR.

  • ersmithersmith Posts: 4,750

    I've updated github so Spin2 member variables are no longer re-arranged. This change will be in the next release.

  • roglohrogloh Posts: 2,957

    Good find Eric!

  • Wuerfel_21Wuerfel_21 Posts: 1,449
    edited 2021-02-25 01:56

    Yep, just grabbed the CI build, works perfectly fine now, even with the PS/2 adapter. Huge thanks for fixing it so quickly!

    Using the Accessory Board buttons for testing in lieu of working keyboard seems to have made me too strong though ;)

    (For the uninitiated, that is a very good score, especially as I got that on the first try with the working keyboard)

  • @Wuerfel_21 said:
    Yep, just grabbed the CI build, works perfectly fine now, even with the PS/2 adapter. Huge thanks for fixing it so quickly!

    Using the Accessory Board buttons for testing in lieu of working keyboard seems to have made me too strong though ;)

    (For the uninitiated, that is a very good score, especially as I got that on the first try with the working keyboard)

    I'm so excited to mess around with VJET (and maybe Spin Hexagon soon too?).

    I broke the pins on my prop-plug and need to dig out the soldering iron to fix it so I can load code again, but this is a big motivator!

  • Wow, thanks guys. I'm glad things got ironed out so quickly 👍.

  • pik33pik33 Posts: 942

    I tried the demo using Propeller Tool. It cannot detect anything in the lower port. The standard cheap keyboard and mouse was detected in the upper port. The mini Raspberry keyboard was not detected. Logitech M215 wireless mouse was also not detected.

  • RaymanRayman Posts: 11,842

    The driver can only handle one port. You can change it to use the lower port by changing the pin assignments...

  • evanhevanh Posts: 10,429

    I've used a marker pen to mark that side where the LED flashes for the upper socket inline with the upper socket, and the other side inline with the lower socket.

  • JRetSapDoogJRetSapDoog Posts: 870
    edited 2021-03-01 05:21

    I'm late to the party, but thanks so much, garyj, for crafting this USB keyboard/mouse driver. Its 3,000 lines of code and comments are a thing of beauty, even though I can only grok about 1% of the whole.

    The driver works with a wired keyboard and an el-cheapo wireless mouse that I used to test it out. And I enjoyed doing some programming for the mouse, as I had never done that before, at least on a Propeller. That was fun.

    About using a smart pin for the event signaling (the "event repository" pin), I wonder what the advantages of that are over just writing values to the HUB, assuming that the latter is even possible timing-wise. I'm guessing that using a smart pin is faster, and possibly more convenient from a programming perspective. Can anyone elaborate? And would a HUB signaling method work?

    Anyway, I used this USB driver alongside a VGA driver. In my particular setup, I have VGA on pins 3 through 7 (vsync, hsync, blue, green red, respectively) and I wanted to place the USB at 0 through 2 (a total of three pins instead of four), but I wasn't sure if the driver could work that way. Fortunately, it can.

    I put the so-called basepin (Event) on pin 2 and put DM on pin 0 (kind of the opposite order from the naming scheme). That worked, but I lost the video signal. I don't have the Parallax Serial Host board, but I checked the schematic and saw that it has an enable signal. Also, when I put a scope probe on pin 3, I saw that the vsync signal was now a constant 3.3 volts (i.e., 3V3 @ 0 Hz). But the other video signals (the DAC-driven ones) were intact.

    So I wandered around in the driver code (which is miles and miles over my head) and found the line "drvh htmp 'Enable the port" on or about line 2033. And after commenting that line out, the vsync signal was back and all was right with the world (video restored). In my case, I don't have an enable signal for protection (though I do use seatbelts while driving), so the three pins (DM, DP and Event) tuck in perfectly with the five pins for VGA (as 3+5=8 pins, with my other pins being occupied).

    As garyj has stated (here and in the code), this USB driver was written with the Parallax Serial Host board in mind, to make things convenient for users. But perhaps a slightly more general Demo would be useful, too, that just lets the user specify the two main pins directly (DM and Event) without using offsets in the constants or code. That is, maybe just specify the DM and Event pins directly in the constants. It's great that garyj has already modified the driver to get those pins from the caller. And maybe the enable pin in the driver could be made optional with a boolean, or just left out entirely, as that could be done in the caller. If the driver is further modified, there might be a little "residual DNA" in the comments at places that could be removed.

    Initially, I was worried that the driver wouldn't allow the Event pin to be specified individually, but it does. Also, there's a comment in the code about the driver needing a "contiguous four-pin block starting at an even pin number." That's true if using the Parallax Serial Host board, which has the enable pin (unless one just tied it high to Vdd, I suppose). But there are apparently no PASM instruction manipulating nibbles (other than for the checksums). And thankfully one can get by with three pins (with the aforementioned commenting out of the enable pin). I'm glad for that because needing to use four pins for USB would put me "over budget" and something else would have to give. Then again, beggars can't be choosy, and I should be thankful to have USB even if it took, say, eight pins.

    Anyhow, what an AMAZING contribution this driver is to the P2 ecosystem. Thanks to Chip for adding a mode for USB signaling, and thanks to garyj for wading deep down in all the USB muck to bring this keyboard/mouse driver to life. I'm sure that it took months and leveraged a ton of existing knowledge and experience.

    @pik33, as you likely know (but for the benefit of other readers), there's also a demo (or two) that shows using two instances of the driver, such that one could utilize both ports concurrently. Doing so takes a second cog, of course. Also, someone mentioned earlier that "neither of the RaspberryPi official keyboard or mouse works" and garyj speculated that "it may be that 'official Pi' devices may not publish that particular {boot} protocol as being available." Perhaps that's also the case with your mini keyboard.

  • pik33pik33 Posts: 942

    The problem with rpi keyboard may be simpler. It has a hub inside and what is seen after connecting the keyboard is this hub.

  • Cluso99Cluso99 Posts: 17,474

    @JRetSapDoog

    I posted modified code for both the VGA driver to use a 4 pin boundary and the prior pin for VS, just like you've used.

    I also posted a mod to garyj's USB driver to use a different signalling pin and IIRC disabled the LED pin. This will get you the 3-pin mode. BTW the signaling via a pin is so interrupts can be used IIRC.

    There is probably a link to these in my RetroBlade - now you have it thread.

Sign In or Register to comment.