Shop OBEX P1 Docs P2 Docs Learn Events
P2 USB Host driver (re-)development thread - Page 5 — Parallax Forums

P2 USB Host driver (re-)development thread

1235715

Comments

  • @pik33 said:
    0483-9005 Interface for a retro DB9 joystick. Works.

    https://allegro.pl/oferta/retrofun-adapter-podlacz-retro-joystick-do-pc-12512264974

    Wow, old-school. An old Atari is it, or for something else like Commodore/Amiga?

  • pik33pik33 Posts: 2,384

    These oldschool DB9 joystick are called "Atari type" but they were used in all home computers: Atari 8bit, Atari ST, C64, Amiga. And this is the interface for connecting such a joystick to the modern PC (and now also to the P2) USB port.

  • pik33pik33 Posts: 2,384
    edited 2023-05-08 08:24

    "tail' not declared

    PUB peek_key() : r
      tail := keyq_tail
      if keyq_head == tail
        return 0 ' No event
      else
        return keyq_data[tail]
    

    .. and it seems something may be wrong with get_key()

    This Basic loop simply prints the received hex code

      do
      let key=kbd.get_key()
      if key<>0 then v.outtextxycg(0,0,v.inttohex(key,8),15,0)
      loop
    

    The result is: if I press a key, I got bit 31 set and the scan code of the previous pressed key. When releasing the key, the scan code is OK.

  • @pik33 said:
    "tail' not declared

    PUB peek_key() : r
      tail := keyq_tail
      if keyq_head == tail
        return 0 ' No event
      else
        return keyq_data[tail]
    

    Oh yea, I never tested that method, just add the variable.

    .. and it seems something may be wrong with get_key()

    This Basic loop simply prints the received hex code

      do
      let key=kbd.get_key()
      if key<>0 then v.outtextxycg(0,0,v.inttohex(key,8),15,0)
      loop
    

    The result is: if I press a key, I got bit 31 set and the scan code of the previous pressed key. When releasing the key, the scan code is OK.

    Hmm, could well be that I fumbled the ring buffer logic in a a slighty obnoxious way, will look into it.

  • @pik33 fixed!

  • Damn, I just grabbed your latest @Wuerfel_21 after your last post here and now it doesn't respond to my keyboard in hidpad_to_vga or keyevent_to_vga. It does seem to update the keyboard boot buffer in the emupad_to_vga program however.

  • @rogloh said:

    • PS3 DualShock3 controller - already reported
      ID=054C0268
      All buttons, sticks & HAT reporting. Right analog Joystick Up and Down both reported in Z-AXIS?

    Well that wouldn't be right - the right analog should have left/right in Z and up/down in RZ - ????? please reconfirm

    • Generic USB game controller (SNES style) works well, all buttons.
      ID=081FE401

    But what are the buttons (numbers)? The press wants to know.

    • Generic control board marketed as "Zero Delay Arcade USB encoder" or "ARC Controller" etc works well
      ID=00790006

    Ok.

  • @rogloh said:
    Damn, I just grabbed your latest @Wuerfel_21 after your last post here and now it doesn't respond to my keyboard in hidpad_to_vga or keyevent_to_vga. It does seem to update the keyboard boot buffer in the emupad_to_vga program however.

    Well that's strange because right now I only really changed the buffer logic (and put in some modifier-related stuff that fell under the table a while ago)

    Can you go back and tell me which commit breaks it?

  • @Wuerfel_21 said:

    @rogloh said:

    • PS3 DualShock3 controller - already reported
      ID=054C0268
      All buttons, sticks & HAT reporting. Right analog Joystick Up and Down both reported in Z-AXIS?

    Well that wouldn't be right - the right analog should have left/right in Z and up/down in RZ - ????? please reconfirm

    They are getting mixed together somehow. Will reconfirm exactly once I get your code downgraded back to a working version...latest broke it.

    • Generic USB game controller (SNES style) works well, all buttons.
      ID=081FE401

    But what are the buttons (numbers)? The press wants to know.

    The buttons were all matching your graphical rendition on screen in emupad_to_vga for this controller. I will check the triggers to see whether it was b5 vs b7 etc.

  • Ok downgraded back to what I think I had yesterday (1732ec0b961324b28259df85f4398a5669b10d19) and I see the controller triggers are b4 and b5 matching left and right on-screen in emupad_to_vga.
    Can't get hidpad_to_vga working (still) things are really flakey now, and I'm not sure what is going on. Still messing about.

  • roglohrogloh Posts: 5,837
    edited 2023-05-08 11:09

    Silly me forgot I rebooted my Mac today and I needed to re-alias "flexspin" back to the latest spin2cpp build folder! It reverted to a different version of flexspin built one day older which silently failed to work right. Damn this tool versioning!

    I do see the PS3 controller working with Z and RZ axes reporting with changes to the right analog stick (L/R = Z, U/D = RZ). I think when I saw this issue before it was just very sensitive to the position but if you hold it centered and carefully move up and down or left and right you can avoid changes in the other axis.

    Update: nice to see the keyboard, mouse and gamepads all working at the same time when pressing keys and game buttons simultaneously and moving the mouse. New key buffer seems to work too.

  • @rogloh said:
    Silly me forgot I rebooted my Mac today and I needed to re-alias "flexspin" back to the latest spin2cpp build folder! It reverted to a different version of flexspin built one day older which silently failed to work right. Damn this tool versioning!

    Happens to the best of us. Though I usually only update my %PATH% flexspin to proper releases and call the hot dev version explicitly with something like ../spin2cpp/build/flexspin

    Don't think it ever happened that I released something that didn't require the very latest flexspin. I'm like a bug magnet.

  • Yeah I like to use a stable toolchain. I temporarily mapped my flexspin via an alias to the latest and greatest yesterday to test it out, but it wasn't also setup in my zshrc file to the same folder. You reboot, forget about it and then bang, broken tools.

  • roglohrogloh Posts: 5,837
    edited 2023-05-08 11:52

    Other good news. I tested out a Microsoft Intellimouse Explorer 2.0 and it worked - no scroll wheel though.

    I also got a Microsoft Wheel Mouse Optical 1.1A mouse working too (same issue with scroll wheel)

    I also got a small wireless Logitech mouse M185 with tiny USB wireless dongle working and its scroll wheel did work with this :) so it could be a good solution for a P2 if you want a 2.4GHz wireless mouse as these are still available cheap.

  • pik33pik33 Posts: 2,384

    I started now to convert my toys to USB... MicroDOS converted (this uses keyboard only), Prop2play to do.

  • The mouse scroll wheel issue should be fixed when I get around to mouse descriptor parsing. Though maybe that'll also reduce overall compatibility, I don't know. The mouse descriptors I've seen aren't too bad.

  • Oh yea, and I think I cought up with all the gamepad compatibility reports.

  • Success with this cheap LogiTech , Model G-UG15 controller. But, the right-side buttons are switched around...

    Cog2 hdev_port = 0, #hdev_id = $046D_C21A, $0000_0000, $0000_0000, $0000_0000, $0000_0000, hdev_bcd = $0004
    Cog2 hconfig_base = $09, $02, $22, $00, $01, $01, $00, $80, $19, $09, $04, $00, $00, $01, $03, $00, $00, $00, $09, $21, $10, $01, $00, $01, $22, $3D, $00, $07, $05, $81, $03, $08, $00, $0A
    Cog2 hdev_intf_idx = 0, hdev_class = $03, hdev_subclass = $00, hdev_protocol = $00
    Cog2 hdev_ep_addr = $0040_8800, (hdev_ep_addr + 1) = $0000_0000, (hdev_ep_addr + 2) = $0000_0000, (hdev_ep_addr + 3) = $0000_0000, (hdev_ep_addr + 4) = $0000_0000, gp_interval = 10, hdev_out_addr = $0000_0000
    Cog2 pb = $7B33, pb = $05, $01, $09, $04, $A1, $01, $A1, $02, $75, $08, $95, $02, $15, $00, $26, $FF, $00, $35, $00, $46, $FF, $00, $09, $30, $09, $31, $81, $02, $75, $01, $95, $0A, $25, $01, $45, $01, $05, $09, $19, $01, $29, $0A, $81, $02, $06, $00, $FF, $75, $01, $95, $06, $25, $01, $45, $01, $09, $01, $81, $02, $C0, $C0
    Cog2 hdev_type = $0000_0006, (hdev_type + 1) = $0000_0000

    emupad_to_vga.spin2 shows that these buttons are off:

    dgately

  • @dgately nice

    To make the button layout right, the rule should be

     * 046DC21A 4 3 2 1 5 6 7 8 9 10 # Logitech Precision G-UG15
    

    You can add the rule to the bottom of the emupad test to verify it (it doesn't load from file for simplicity)

    Can give me that PNG, but not annotated?

  • @Wuerfel_21 said:
    You can add the rule to the bottom of the emupad test to verify it (it doesn't load from file for simplicity)
    Can give me that PNG, but not annotated?

    Adding that rule works!

  • roglohrogloh Posts: 5,837
    edited 2023-05-09 04:12

    @Wuerfel_21
    Messing about with your code a bit I think it probably makes sense to have some way to set the existing mouse co-ordinates from the client side which I didn't see in the existing USB mouse API - I know it's still early days. This could then control where the mouse cursor is currently situated on screen, both at startup (e.g to default it in the centre of a window instead of top left), or just if you need to reposition it from some application code for any reason later. Something like a usb.mouse_set_pos(x,y) would be good for example.

    If we had this functionality it would be nice:

    • init/detect mouse presence or reattachment
    • set/get mouse pos
    • get button states
    • set boundary limits
    • maybe in the future some API to set scaling or possible acceleration params used by the low level driver to compute co-ordinates

    Now you have a basic USB mouse working I'm also considering extending my p2textdrv API to provide a few more APIs to show/hide the mouse and return where the co-ordinates are to be updated in HUB RAM so you don't have to inconveniently bypass my API layer as you discovered you needed to.

    Probably I should try to add something like this to a future p2textdrv.spin2:

    ' mouse methods
    
    PUB showMouse(spritedata, xhot, yhot)
        video.setMouseImage(@region, spritedata, xhot, yhot) ' setup a mouse sprite and its hot spot co-ordinates
        video.showMouse(@region, 0) ' enable display of a global mouse
    
    PUB hideMouse()
        video.hideMouse(@region) ' hide the mouse
    
    PUB getMouseAddr() : addr
        return @display + 28 ' returns address of x,y co-ordinate long for global mouse
    

    You could then enable the mouse on a (4bpp text) screen with something like this:

    usb.start()
    usb.mouse_set_limits(640-1,480-1)
    usb.mouse_set_outptr(text.getMouseAddr())
    text.showMouse(@mouse4bpp, 4, 0)) ' show the mouse
    

    In an application the button states and co-ordinates should of course be read from the USB mouse API itself. If required an on screen mouse sprite can still change its pattern dynamically by continuing to call showMouse after startup, passing the updated image data from the client. This can occur if you want to move over text boxes or other screen elements and change its style/colour etc. This is mostly needed in graphics environments, less so for pure text screens unless you have a TUI, but useful nonetheless.

  • pik33pik33 Posts: 2,384
    edited 2023-05-09 07:49

    Set mouse position is needed in the USB driver to avoid translation when the application itself (and not the user) needs to move the mouse pointer. Also, in this convention where we have x, y and z, it should be usb.mouse_set_pos(x,y,z) . Or usb.mouse_set_pos(x,y) and usb.mouse_set_wheel(z)

  • The reason position set isn't implemented is because it's tricky to do without edge cases (set ignored when it happens at the same time as polling). If you want to do funky stuff do it in the application and update the screen cursor yourself.

    Am on the move, more later..

  • roglohrogloh Posts: 5,837
    edited 2023-05-09 08:44

    @Wuerfel_21 said:
    The reason position set isn't implemented is because it's tricky to do without edge cases (set ignored when it happens at the same time as polling). If you want to do funky stuff do it in the application and update the screen cursor yourself.

    Yeah I've been fighting this today trying to figure a way that is workable and handles corner cases. Not so simple as you mention. Here's what I was thinking:

    In some SPIN2 mouse_set_xyz(x,y,z) API:

    • set a mouse position update "software lock" flag
    • small delay to account for driver's critical section timing between its HUB reads and its write back operations (probably just a couple of hundred P2 clocks or so, needs to be given a sufficiently large delay)
    • update HUB x,y,z accumulators to the new x,y,z values
    • update mouse sprite X,Y position long (if this is not done the mouse won't move on screen until the mouse is physically moved)
    • clear mouse position update lock flag

    In the USB driver's mouse report handler code:

    • the mouse report occurs
    • read mouse position update flag from HUB
    • read current x,y,z accumulator values from HUB
    • do normal mouse processing with x,y,z increment/decrement computations, and handle button state changes
    • update button state to HUB RAM but only write back new x,y,z accumulators if update flag was cleared when it was read
    • update mouse sprite X,Y position long if update flag was clear

    I think this should work but I will try it.

  • A better question: why?
    What's the point of yoinking the cursor position?

  • pik33pik33 Posts: 2,384
    edited 2023-05-09 08:52

    @rogloh said:

    @Wuerfel_21 said:
    The reason position set isn't implemented is because it's tricky to do without edge cases (set ignored when it happens at the same time as polling). If you want to do funky stuff do it in the application and update the screen cursor yourself.

    Yeah I've been fighting this today trying to figure a way that is workable and handles corner cases. Not so simple as you mention. Here's what I was thinking:

    In some SPIN2 mouse_set_xyz(x,y,z) API:

    • set a mouse position update "software lock" flag
    • small delay to account for driver's critical section timing between its HUB reads and its write back operations (probably just a couple of hundred P2 clocks or so, needs to be given a sufficiently large delay)
    • update HUB x,y,z accumulators to the new x,y,z values
    • update mouse sprite X,Y position long (if this is not done the mouse won't move on screen until the mouse is physically moved)
    • clear mouse position update lock flag

    In the USB driver's mouse report handler code:

    • the mouse report occurs
    • read mouse position update flag from HUB
    • read current x,y,z accumulator values from HUB
    • do normal mouse processing with x,y,z increment/decrement computations, and handle button state changes
    • update button state to HUB RAM but only write back new x,y,z accumulators if update flag was cleared when it was read
    • update mouse sprite X,Y position long if update flag was clear

    I think this should work but I will try it.

    It can be done simpler. We need 3 variables in the driver for new x,y and z, initialized at something negative, eg $80000000. The Spin method simply sets them with given values. The asm code, while updating the mouse position, checks if these variables are positive. If yes, instead of adding deltas to positions, rewrite them with new values, then set new variables to $80000000 again.
    I want now to add the driver to prop2play, so I can experiment with this.

  • Btw, mouse presence detection couls be easily added, but is a bad idea. A mouse interface configured != A mouse physically exists != The user wants to use the mouse.

    The correct way to show/hide the cursor in a mouse-optional application is to start showing it when the mouse is moving and, if desired, hide it when it stops moving or keyboard navigation is engaged.

  • roglohrogloh Posts: 5,837
    edited 2023-05-09 09:02

    @Wuerfel_21 said:
    A better question: why?
    What's the point of yoinking the cursor position?

    In general you don't need to, but maybe you want to center the mouse cursor at startup so it's immediately visible, or if you had two COGs sharing the display and each had their own cursor position state you could hit some key to flip the window and the mouse position could be retained from prior session/window etc. There are a few use cases, but admittedly not that many.

    Region mice are other things possible in my driver - each region can have its own mouse sprite not just a single global one. Maybe you want to multiplex a single physical device in different window regions with different co-ordinates (but not simulataneously - that'd be crazy).

  • pik33pik33 Posts: 2,384

    Yes, the app can show the cursor when mouse move detected and, for example, hide it after a timeout without moving.

  • pik33pik33 Posts: 2,384

    7-port hub strange behavior: 4 ports works of 7 available. I'd be less surprised if only 3 were working: that would mean the second hub in the chain is not supported.

Sign In or Register to comment.