fruit-bat / pico-zxspectrum

ZX Spectrum for Raspberry Pico Pi RP2040
453 stars 48 forks source link

Compiling with USB and Keyboard mapping question ? #66

Open ArnoldUK opened 1 year ago

ArnoldUK commented 1 year ago

I'm compiling the source on raspbian which is all setup and building fine but not sure which git source to use for the pico_sdk_extras with TinyUSB sources for HID keyboard. I'm currently following the instructions in the readme which is to delete the original TinyUSB and use the following for TinyUSB: cd $PICO_SDK_PATH/lib/ mv tinyusb tinyusb.orig git clone git@github.com:fruit-bat/tinyusb.git cd tinyusb git checkout hid_micro_parser Is this correct as conflicting info in the readme suggested by Ryzee119 are getting harder to merge into the latest code ? What is the correct way to make sure the TinyUSB sources are cloned from git ?

Also, attempting to remap the keyboard GPIO I found this defined macro function in pzx_keyscan.map #define CP_JOIN_PZX(a) ((a & 15) | ((a >> 3) & (7 << 4))) What exactly does this function do and what do and how does it relate to the other defines set for the GPIO Pins: #define CN_PZX 7 #define RN_PZX 7 #define CP_PZX 19, 20, 21, 22, 26, 27, 28 #define RP_PZX 8, 9, 14, 15, 16, 17, 18 #define CP_SHIFT_PZX 19 Thanks and this a really interesting project to work on! Hoping to contribute somthing myself when I'm familair with the source code.

fruit-bat commented 1 year ago

I should remove the notes about the Ryzee119 pull request, it is probably not relevant anymore. The instructions as written should work fine. Every now and then I try to merge in changes from TinyUSB proper into my fork (although I haven't for a while).

Both directly connected USB devices and a single layer of USB hub seem to work... mostly. My fork of TinyUSB contains changes to allow parsing of HID reports, which allows me to connect joysticks. I do have a pull request in with TinyUSB but I'm not sure it is going to get merged.

Be aware that there is another key scan routine for the ZxSpectrumBreadboardHdmiKbd1PinAudio target. See ZxSpectrumKeyMatrix.h & ZxSpectrumKeyMatrix.cpp This target provides HDMI output and keyboard scanning, with the assistance of a shift register.

To read the keyboard columns efficiently, I make a single call to gpio_get_all() and then mess about with the response so the column bits are in the lower end of an int32 in the correct order. i.e. uint32_t a = ~(gpio_get_all() >> CP_SHIFT); uint32_t r = CP_JOIN(a);

The pins are scattered differently for the various bits of supported hardware, so I use a #define to gather them back together and shift them into position...

define CP_JOIN_PZX(a) ((a & 15) | ((a >> 3) & (7 << 4)))

define CP_SHIFT_PZX 19

// Column count

define CN_PZX 7

// Row count

define RN_PZX 7

// Column pins

define CP_PZX 19, 20, 21, 22, 26, 27, 28

// Row pins

define RP_PZX 8, 9, 14, 15, 16, 17, 18

// Bits to shift all gpio response to the right before 'joining' column bits

define CP_SHIFT_PZX 19

And as a final point, I'm not sure if the columns are actually physical columns on the keyboard. I wrote the code and then pressed the buttons to get the mappings (sorry!).

ArnoldUK commented 1 year ago

Thanks for the quick response, very helpful indeed. Your TinyUSB implementation works fine BTW I don't have any issues with the USB HID devices, everything I've connected (joysticks, bluetooth keyboards etc..) all work perfectly.

As for the keyboard scanning routines, yes I noticed the shift register setup but I was wanting to avoid using extra components as I can do the scanning all through the pi if I can work out your bit shifting functions :) I'm currently using this layout for a 6x8 keyboard layout: #define CN_PZX 8 #define RN_PZX 6 #define CP_PZX 18, 19, 20, 21, 22, 26, 27, 28 #define RP_PZX 8, 9, 14, 15, 16, 17 #define CP_SHIFT_PZX 18 #define CP_JOIN_PZX(a) ((a & 15) | ((a >> 3) & (7 << 4))) But the CP_JOIN_PZX function is failing until I can work out the bit shifting for the columns. I may end up doing what you suggested and tap away at buttons manually.

Much appreciate your help!

fruit-bat commented 1 year ago

Does this help...

1) Write backwards 28, 27, 26, 22, 21, 20, 19, 18 1) 28, 27, 26, 22, 21, 20, 19, 18 >> 18 -> 10, 9, 8, 4, 3, 2, 1, 0 (note the gap between 22, 26 and 4, 8) 2) mask off lower bits (Column 0 -> Column 4)

10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0
 0  0  0  0  0  0  1  1  1  1  1  = 31

3) Shift and mask the higher bits 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 >> 3 -> 7, 6, 5, 4, 3, 2, 1, 0

  7, 6, 5, 4, 3, 2, 1, 0 (Column 7 - Column 5 in the upper 3 bits)
  1  1  1  0  0  0  0  0  = 7 << 5 

4) bitor the two fragments

define CN_PZX 8

define RN_PZX 6

define CP_PZX 18, 19, 20, 21, 22, 26, 27, 28

define RP_PZX 8, 9, 14, 15, 16, 17

define CP_SHIFT_PZX 18

define CP_JOIN_PZX(a) ((a & 31) | ((a >> 3) & (7 << 5)))

ArnoldUK commented 1 year ago

Amazing bit juggling, I know it's much faster working on bits rather than bytes but I'm not that low level when it comes to coding, much prefer working with bytes. Anyway, I will give your code a try later tonight and give you the thumbs up. The function is much much clearer to me now, thanks for that.

ArnoldUK commented 1 year ago

Well that worked remarkably well using the updated CP_JOIN_PZX function. 99% working now apart from the shifted keys as there does not appear to be a HID_KEY_SHIFT defined and the kbits matrix array uses a 0 for CAPS_SHIFT ?

I'm working on interfacing the original 48K keyboard matrix along with 8 extra keys for the menu stuff. I've also coded the firmware for using a 48K spectrum keyboard through USB which runs entirely on a vanilla ATMega328 MCU using V-USB (those Teensy's are getting too pricey).

I will upload all the code updates along with instructions how to interface a 48K keyboard membrane to the pico-zxspectrum on my github page (sorry i'm not savvy with github). I'm aware of the breadboard build that uses a shift register but that only supported HDMI and is a work in progress. I wanted to avoid external components and keep all the keyboard mapping on the pico along with VGA output.

@fruit-bat Cheers for your help with this!

fruit-bat commented 1 year ago

Excellent, glad that helped 🙂 There are some extra defines around line 186 for which you may need your own section and values.

ArnoldUK commented 1 year ago

Yeah, I located the cursor and shift defines :

define KEY_SHIFT_ROW 0

define KEY_SHIFT_BIT 0x20

Should be easy enough to work out now I have the complicated bits out of the way. I'm simply using an extra #define in the CMAKE file and pzx_keyscan.cpp files to make it easier to select between the 2 keyboard matrix setups when building.

When I have it fully tested I'll upload my updates along with some schematics, PCB layouts and other documents. Good working with you. Oh and Happy New Year!

fruit-bat commented 1 year ago

I look forward to seeing your changes and PCB layouts!

Happy New Year to you too 🎉

ArnoldUK commented 1 year ago

I've uploaded my code changes and schematic to my github page I have all the keys working along with SHIFT and SYMBOL SHIFT. There are also 8 extra external buttons that can used for Menu and Keyboard Joystick controls etc.. I'm not too good with github but I'm sure you can add this quite easily without me breaking things.

fruit-bat commented 1 year ago

@ArnoldUK Thanks for sharing your changes. I will have a go at adding a new target for your setup. Is it ok if I add your circuit diagram along with the description of the configuration to my readme?

ArnoldUK commented 1 year ago

Sure, use and modify whatever you see. The schematic is a modified copy that I think was originally designed by Misenko. I was going to implement a special key sequence on the spectrum keyboard to bring up the F1 Menu but this breaks the pure 48K mode keyboard as all keys are used for speacial characters. I'm happy with having a simple external push button to bring up the menu though. I've got more features to add but still testing things at the moment.

EDIT: I've now realized that CAPS SHIFT + SYM SHIFT + SPACE could be coded to bring up the F1 Menu but after 2nd thoughts those keys may conflict with any keys defined within some games. I like to play my games hardcore on the spectrum keyboard :)

fruit-bat commented 1 year ago

I've added some code and pull-requested to myself so we can see what has changed. https://github.com/fruit-bat/pico-zxspectrum/pull/67/files

The code just on a branch for now: https://github.com/fruit-bat/pico-zxspectrum/tree/feature/auk

There is a pre-built target, please would you let me know if it works. https://github.com/fruit-bat/pico-zxspectrum/blob/feature/auk/uf2/ZxSpectrumPicomputerVgaAuk.uf2

There was a bit of code that I have removed using a #ifndef which switches the arrow keys to be a Kempston joystick, rather than the keyboard arrows. The code was trying to use a value off the end of the array. I am guessing you do not need it.

ArnoldUK commented 1 year ago

Thanks for that, I will try your pre-built release tonight and update you with the results. The extra fork is a good idea also. As for the cursor keys issue, I did notice this in the menu screen but put it down to not having an sd-card inserted.

ArnoldUK commented 1 year ago

Your pre-built release works but I was having make errors part way through building the source myself. Make error 2 kept popping up at random places, not sure what that could be. I could however build the source without errors when I used the original CMakeLists from the main branch. Maybe a typo somewhere but I don't know much about CMake to look for errors.

I've updated my Schematic to Rev 1.1 as I have the COL GPIO Pins on the Pico in the wrong order. The COL1 Should start from GPIO 18. Also the Key Mapping in pzx_keyscan.cpp for the ROM switching should HID_KEY_F11, HID_KEY_F12

Apart from the above all appears to work very well. I can access the menu and navigate around using the number keys but not sure on how to assign or use a key for ESC within the menu.

fruit-bat commented 1 year ago

Thanks for the updates. It looks like ESC is already mapped to shift-enter/fire (one of your extra buttons). It's a bit awkward but should work. The key mapping get surprisingly tricky when you have limited physical buttons and two systems to overlap!

fruit-bat commented 1 year ago

Hi, I've added your latest changes and updated the binary. Sorry it took a while. The changes are now on the main branch.

I was wondering if you were happy with the mapping for ESC... You could have a single reset button, which would reset to the current mode (and rely on the menus to swap between 48k and 128k mode). This would free up a button for 'back' on the menus.

ArnoldUK commented 1 year ago

Thanks for the code update to main branch. I'm fine with the key mappings, as long as I've got the full functionality of the speccy keyboard. Yes, the ROM switching can be done through the menu but as it is I will stick with the extra buttons. I was going to add a key sequence press on the keyboard to invoke the ESC key but the speccy keyboard uses all the keys, so I won't worry too much about that for now.

I'm working on a config file now to read from the SDCard and add more functionality.

fruit-bat commented 1 year ago

Sound good. If you commit your changes to the feature/auk branch in your fork then we can pull-request them back to the same branch in my repository.

ArnoldUK commented 1 year ago

Sure I will do that. I'm a bit of a newbie with github but now I've started to use it, I find it very useful.

fruit-bat commented 1 year ago

Git & GitHub are really good. Do ask if you are not sure about something.

BrettRogersUK commented 8 months ago

Hi @ArnoldUK, I'm going to make my own PCB eventually based on your updated schematic to use a proper speccy keyboard. I'm wondering if it would be possible to have the HDMI instead of the VGA connector?