mitxela.com forum
Welcome. Please log in or register.

Next »Pages: [1] 2

Bluetooth HID gamepad extra buttons
Shadowtrance Posted: 17 Sep 2017, 06:05 AM
Avatar


Member
Posts: 8
Joined: 16-September 17
Hi there. :)
Firstly, thanks for posting this project, just what i was looking for (and found after much googlefu haha).

Now, i have basically zero clue about asm (i already have it up and running as is with your code) but was wondering how you'd go about expanding the button count with the spare pins available?
I count 5 free pins unless I'm missing something. haha
I only really want 2 extra but couldn't hurt to get an idea of how to make use of the spare pins.

Thanks :)

-------------
[top]
mit Posted: 17 Sep 2017, 10:09 AM
Avatar
yeah whatever

Admin
Posts: 538
Joined: 4-May 16
Hi, yeah the default report descriptor lets you have up to 16 buttons.

It's super convenient to use all 8 pins on port B, we can read the port and stick that straight into the uart message. But the other GPIO pins are kinda scattered, there's 3 on port A, and a few spare on port D.

You need to set up an unused register, say r24, and after reading the pins you want, stick all of the bits in there. Then use another one, say, r25, to be the previous state, and add another line to the compare, something like

    cp r20, r19          ; Only transmit if input state has changed
cpc r18, r17
cpc r24, r25
breq main


since compare-with-carry can be chained like that. Then just before the last sendByte call, change the load 0 to be a mov r16, r24.

Or... you could rewrite the program in C if it's easier. It is a very short program after all.

Last edit by mit at 17 Sep 2017, 10:09 AM

-------------
[top]
Shadowtrance Posted: 17 Sep 2017, 05:41 PM
Avatar


Member
Posts: 8
Joined: 16-September 17
Well I'm getting somewhere, sort of...

PA0 and PA1 work as button inputs, but now those buttons (9 and 10) light up when any other button is pressed and they stay lit up until i press 9 or 10 then they register their presses but are still lit up if not pressed anyway.

Like so...me pressing button 4.
(User posted image)


Not sure what I'm missing, probably something simple no doubt. haha
Would like to get button 11, 12 and 13 (PA2, PD0, PD6) working too if possible but will just work on 9 and 10 first and go from there. :)

Bold red is the parts i added/changed.

;;;;;;;;;;;;;;;;

ldi r16, 1<<PD1 ; UART Tx
out DDRD, r16
ldi r16, 0
out DDRB, r16

ldi r16, 0 ; new pins
out DDRA, r16 ; new pins


ldi r16, $FF ; Buttons 1-8
out PORTB, r16
ldi r16, 0b00111100 ; D-pad
out PORTD, r16

ldi r16, 0b00000011 ; new pins
out PORTA, r16 ; new pins


ldi r16, 8 ; UART 115200bps
out UBRRL, r16
ldi r16, 0
out UBRRH, r16
ldi r16, 1<<U2X
out UCSRA, r16
ldi r16, 1<<TXEN
out UCSRB, r16

main:
in r17, PINB
com r17

in r19, PIND
andi r19, 0b00111100

in r23, PINA ; new pins
andi r23, 0b00000011 ; new pins


cp r20, r19 ; Only transmit if input state has changed
cpc r18, r17
cpc r24, r23 ; new pins
breq main

clr r21 ; X
clr r22 ; Y

sbrs r19, 2 ; Left
subi r21, 127

sbrs r19, 3 ; Up
subi r22, 127

sbrs r19, 4 ; Right
subi r21, -127

sbrs r19, 5 ; Down
subi r22, -127

ldi r16, $FD
rcall sendByte
ldi r16, $06
rcall sendByte

mov r16, r21
rcall sendByte

mov r16, r22
rcall sendByte

ldi r16, $00
rcall sendByte

ldi r16, $00
rcall sendByte

mov r16, r17
rcall sendByte

mov r16, r23
rcall sendByte ; new pins



mov r18, r17 ; Store input states of last transmit
mov r20, r19
mov r24, r23 ; new pins

rjmp main


sendByte:
sbis UCSRA,UDRE
rjmp sendByte
out UDR, r16
ret


-------------
[top]
mit Posted: 17 Sep 2017, 10:39 PM
Avatar
yeah whatever

Admin
Posts: 538
Joined: 4-May 16
Ah, you're nearly there. The pins are high (logic 1) when idle, and pulled low to ground (logic 0) when the button is pressed. But we want them to be logic 1 when pressed. The 'com' instruction inverts all bits in a register. So

    in r23, PINA ; new pins
andi r23, 0b00000011 ; new pins


should be

    in r23, PINA ; new pins
com r23 ; new pins


PA2 is actually the reset pin so you probably can't use it, without disabling ISP programming. The port D pins you will need to check, and then change the value of r23 accordingly.


-------------
[top]
Shadowtrance Posted: 18 Sep 2017, 12:27 AM
Avatar


Member
Posts: 8
Joined: 16-September 17
Ah yep that did the trick. :)

Another issue appeared after that was changed though, buttons 11 - 16 go high and stay high when any other is pressed (in the game controller test thing). hmm

Can't seem to get any life out of PD0 and PD6 at all for some reason, i figured changing 0b00111100 in the d-pad part/s to 0b01111101 would do the trick but it doesn't seem to be the case.

I AM just figuring this out as i go though so bare with me. haha Not really a software guy, more of a hardware tinkerer. :)

-------------
[top]
mit Posted: 18 Sep 2017, 10:38 PM
Avatar
yeah whatever

Admin
Posts: 538
Joined: 4-May 16
QUOTE
buttons 11 - 16 go high and stay high when any other is pressed

Oh yeah that'll happen. You can stop it by still doing the immediate AND after the com, so:

    in r23, PINA ; new pins
com r23 ; new pins
andi r23, 0b00000011 ; new pins


Doing an AND with a bitmask like that will set the top six bits to zero, so setting the other buttons to be unpressed.

To make use of the other pins on port D... lets see, you'd want to shuffle things around a bit. If you move the logical AND for r19 down a bit, to after the r23 stuff, you can check r19 for the pins and then set bits in r23 accordingly. Something like:


in r19, PIND

in r23, PINA ; new pins
com r23 ; new pins
andi r23, 0b00000011 ; new pins

sbrs r19, PD0
sbr r23, 0b00000100

sbrs r19, PD6
sbr r23, 0b00001000


andi r19, 0b00111100
cp r20, r19 ; Only transmit if input state has changed
cpc r18, r17
cpc r24, r23 ; new pins
breq main


sbrs is "skip (the next instruction) if bit in register is set"
sbr is "set bits in register"

There's also sbrc, "skip if bit in register is clear" to reverse the logic there. I've not tested the code above but it should work.

-------------
[top]
Shadowtrance Posted: 19 Sep 2017, 01:25 AM
Avatar


Member
Posts: 8
Joined: 16-September 17
Yep the first part fixed that issue with 11-16 going high etc.

As for PD0 and PD6 strange things happen.

For example, press button 1, both 11 and 12 light up (as well as 1 as it should) and sometimes blink a few times or just constantly blink but also stay lit up if not blinking randomly.

And complete code with current changes with the odd behaviour... Don't think i did anything wrong, or did i? haha hmm

ldi r16, 1<<PD1 ; UART Tx
out DDRD, r16 ; BT RX -> Attiny2313 PD1 TX

ldi r16, 0 ; Buttons 1-8
out DDRB, r16 ; PB0 - PB7

ldi r16, 0 ; Buttons 9 - 10
out DDRA, r16 ; PA0 - PA1

ldi r16, $FF ; Buttons 1-8
out PORTB, r16 ; PB0 - PB7

ldi r16, 0b00111100 ; D-pad
out PORTD, r16 ; PD2 - PD5

ldi r16, 0b00000011 ; Buttons 9 - 10
out PORTA, r16 ; PA0 - PA1

ldi r16, 8 ; UART 115200bps
out UBRRL, r16
ldi r16, 0
out UBRRH, r16
ldi r16, 1<<U2X
out UCSRA, r16
ldi r16, 1<<TXEN
out UCSRB, r16

main:
in r17, PINB ; Buttons 1-8
com r17

in r19, PIND ; D-pad

in r23, PINA ; Buttons 9 - 10
com r23
andi r23, 0b00000011

sbrs r19, PD0 ; Button 11
sbr r23, 0b00000100

sbrs r19, PD6 ; Button 12
sbr r23, 0b00001000

andi r19, 0b00111100
cp r20, r19 ; Only transmit if input state has changed
cpc r18, r17
cpc r24, r23
breq main

clr r21 ; X
clr r22 ; Y

sbrs r19, 2 ; Left
subi r21, 127

sbrs r19, 3 ; Up
subi r22, 127

sbrs r19, 4 ; Right
subi r21, -127

sbrs r19, 5 ; Down
subi r22, -127

ldi r16, $FD ; HID raw report descriptor
rcall sendByte
ldi r16, $06 ; Length
rcall sendByte

mov r16, r21 ; Right X Axis
rcall sendByte

mov r16, r22 ; Right Y Axis
rcall sendByte

ldi r16, $00 ; Left X Axis
rcall sendByte

ldi r16, $00 ; Left Y Axis
rcall sendByte

mov r16, r17 ; First 8 buttons
rcall sendByte

mov r16, r23 ; Last 8 buttons
rcall sendByte


mov r18, r17 ; Store input states of last transmit
mov r20, r19
mov r24, r23

rjmp main


sendByte:
sbis UCSRA,UDRE
rjmp sendByte
out UDR, r16
ret


-------------
[top]
mit Posted: 19 Sep 2017, 05:24 PM
Avatar
yeah whatever

Admin
Posts: 538
Joined: 4-May 16
Hmm, things happening randomly, might be just that the input pullups are not set for those pins, might be something else.

Try changing

    ldi r16, 0b00111100     ; D-pad
out PORTD, r16 ; PD2 - PD5

to

    ldi r16, 0b01111101     ; D-pad
out PORTD, r16 ; PD2 - PD5

which should turn the pullups on for pins D0 and D6.

-------------
[top]
Shadowtrance Posted: 19 Sep 2017, 06:42 PM
Avatar


Member
Posts: 8
Joined: 16-September 17
And now it is perfect. :)

No strange things happening, everything just doing what it is supposed to. :)

Once again, thanks for sharing your projects and taking the time to help a noob who knows pretty much nothing about asm through it.

I tried the arduino sketch another user posted with their fight stick but X Y isn't implemented and to be honest the arduino side of things is just giving me a headache. haha I'll get that working one day i guess.

I'll be sure to stop by and check out more projects or maybe just say hi. :)

Edit: And now it's out there for the world to see some more, hope you don't mind. :)

https://github.com/Shadowtrance/BluetoothHidGamepad

Last edit by Shadowtrance at 19 Sep 2017, 07:19 PM

-------------
[top]
mit Posted: 21 Sep 2017, 06:43 PM
Avatar
yeah whatever

Admin
Posts: 538
Joined: 4-May 16
Cool.

You have quite a few more repos on there than I do. I should totally get in to all that DS hacking stuff.

-------------
[top]
Shadowtrance Posted: 21 Sep 2017, 07:51 PM
Avatar


Member
Posts: 8
Joined: 16-September 17
Yeah I'm not really into the 3ds hacking stuff anymore. I was pretty involved in the scene a while ago. :)

A lot of the repo's are just forks, a couple of my own written stuff and some contributed to.

In other news, i got one of my projects based on this pretty much done. :)

12 button fight stick (old tekken 6 xbox 360 wireless), just about useless for anything but PC (still need drivers/wireless dongle which can be annoying) and xbox 360(obviously). Re-purposed the guide button as the L3 button and the sync button as the R3 button, well button 11 and 12 anyway.

Just need to set up a better power circuit with rechargeable lipo / li-ion battery and we're good besides taming the wire mess inside haha Works as is atm with 2 AA batteries though reusing the battery holder already there.

I WAS going to do a snes controller (original, not a clone) but i have no idea how i'd fit everything in there to be honest. haha So I'll leave that one for another day.

Might not be pretty on the inside but hey it works!

(User posted image)

(User posted image)


-------------
[top]
mit Posted: 25 Sep 2017, 07:59 PM
Avatar
yeah whatever

Admin
Posts: 538
Joined: 4-May 16
Looks good. One of the easiest ways to add a rechargable lipo is to just get a USB power bank, it comes with all the charging circuitry and boost converter in one unit, looks like you have room in the case for one.

Original SNES controller would be awesome but yeah, you'd need to think carefully about how to fit the battery in there.

-------------
[top]
Shadowtrance Posted: 6 Nov 2017, 01:53 PM
Avatar


Member
Posts: 8
Joined: 16-September 17
Hey mit me again. :)

So far this has been working great, finally got rechargeable lipo setup installed etc.

I'm curious if you've used your controller (the snes pad) in retropie/emulationstation at all?

I have an odd issue with only that, works perfect on pc games and the rpi with retroarch menus, in game etc but in emulationstation itself moving up/down will actually skip ahead 2 items in the menu, so i'm at item 1 in the list, hit down (flick the stick down, not hold), jumps to 4 etc etc jumps 2 ahead every time.
Now if i HOLD the stick up or down direction it moves one by one as it should..well, same as any other controller, pretty quickly moves down the list. Seems to happen with left/right too but don't notice as much because most of the menus are vertical. Doing it the hold stick way is a pain in the butt to get it to stop where i want though. haha

It's kinda strange and i can't figure it out. :(

Only seems to be related to this controller setup AND emulationstation together (rpi or pc version, doesn't matter), doesn't do it with my dualshock 4 or original snes controller running through usb with a raphnet snes > usb adapter. Obviously the DS4 works differently as the DPAD is set as a hat switch, the snes pad though is simple XY like this is.

So i thought you may have some thought on why it's doing it.

Thanks again. :)

Last edit by Shadowtrance at 6 Nov 2017, 01:55 PM

-------------
[top]
mit Posted: 9 Nov 2017, 02:12 AM
Avatar
yeah whatever

Admin
Posts: 538
Joined: 4-May 16
Hi Shadowtrance, sorry I probably can't help much with this one, I've not used emulationstation. My controller works fine with Zsnes which is the only thing I use it for really.

Usually when things jump two spaces in a menu it means there needs to be some debouncing. Often if the metal contacts inside switches bounce a tiny bit it can register as two presses instead of one. If that's the problem it could be quite easy to solve, such as putting a small capacitor on the contacts. But if it's jumping the menu every single time, that might not be the problem.

If the controller is fine in other emulators, maybe it's just emulationstation that doesn't like it? There's probably a way to re-map the joystick in software so that it appears as a pov hat instead of an axis.

-------------
[top]
Shadowtrance Posted: 9 Nov 2017, 06:35 AM
Avatar


Member
Posts: 8
Joined: 16-September 17
Yeah it jumps 2 ahead every single time without fail ONLY in the emulationstation menus so it is only an emulationstation issue as it doesn't do it anywhere else.

Didn't think of the debouncing thing, might have to try some different methods. Although i guess that probably isn't the issue.

As for mapping the stick to pov hat instead of an axis i have no idea to be honest, the controller setup just takes the input you give it, in this case X+ X- Y+ Y- for up down left right input. Tried changing it manually in the config file, it didn't work. :(

And I'm guessing we can't map it as a pov hat in code due to the way the rn42 handles the raw commands for joystick.

This is how it is recognized in the input config (after setting it up via the gui).

First is the arcade stick via bluetooth setup.

<inputConfig type="joystick" deviceName="ARCADEBT" deviceGUID="05000000415243414445425400000000">
<input name="pageup" type="button" id="9" value="1"/>
<input name="start" type="button" id="4" value="1"/>
<input name="up" type="axis" id="1" value="-1"/>
<input name="a" type="button" id="0" value="1"/>
<input name="b" type="button" id="1" value="1"/>
<input name="down" type="axis" id="1" value="1"/>
<input name="pagedown" type="button" id="8" value="1"/>
<input name="right" type="axis" id="0" value="1"/>
<input name="x" type="button" id="3" value="1"/>
<input name="select" type="button" id="5" value="1"/>
<input name="y" type="button" id="7" value="1"/>
<input name="left" type="axis" id="0" value="-1"/>
</inputConfig>


Second is my original snes controller via usb with my homemade raphnet snes usb board. i actually use this one which handles more than just snes http://www.raphnet.net/electronique/atari_usb/index_en.php

<inputConfig type="joystick" deviceName="raphnet.net (S)NES/Atari_USB" deviceGUID="0300000081170000960a000001010000">
<input name="pageup" type="button" id="6" value="1"/>
<input name="start" type="button" id="3" value="1"/>
<input name="up" type="axis" id="1" value="-1"/>
<input name="a" type="button" id="4" value="1"/>
<input name="b" type="button" id="0" value="1"/>
<input name="down" type="axis" id="1" value="1"/>
<input name="pagedown" type="button" id="7" value="1"/>
<input name="right" type="axis" id="0" value="1"/>
<input name="x" type="button" id="5" value="1"/>
<input name="select" type="button" id="2" value="1"/>
<input name="y" type="button" id="1" value="1"/>
<input name="left" type="axis" id="0" value="-1"/>
</inputConfig>


As you can see they're both pretty much the same except button numbers (and i guess 4 microswitches vs dpad contacts) which is why it's even more puzzling.

hmm it has me kinda stumped to be honest. haha

Umm yeah, i dunno. kinda just sharing now and trying to demystify this i guess, which probably won't happen. haha

-------------
[top]

Next »Pages: [1] 2

Sign in to post a reply.