BX portable game console | project collaboration


Hi all,

So I designed a PCB:

It has:

  • 1 TinyFPGA-BX socket
  • 1 320x240 LCD screen socket
  • 8 buttons
  • 1 audio out jack
  • 2 battery holders to power the console with 4xAAA
  • 1 on/off switch
  • 1 serial output

The board is 160x64mm.

If you are interested, I can order a small batch.
We have multiple options:

  • For bare PCB only it will be around ~15 euros delivered to you
  • For assembled boards (without the screen, BX and headers) ~70 euros delivered to you
  • For assembled boards with screen (without BX and headers) ~85 euros delivered to you

Let me know if you are interested.


Super cool! I’d be interested in an assembled board, if you are doing a run.


Very cool! Would be great to have an orientation marker on the PCB for the BX module.

Maybe optional headers for the surface mount header on the bottom of the BX.

Ohh, and a slot for a lanyard so it can be worn as a badge!

Count me in for two with an LCD! :smile:


Hi Luke,

This version is a semi-DIY/semi-assembled. For instance, the screen could be assembled directly on the board with a flat-flex connector instead of using the eval board from buydisplay.com like I did here.
The pads between the legs of the BX are passives for the audio output, I hide them under there.

I can do a full DIY version with only though holes components.
Maybe it is actually better for the first version.


Yes, I am interested. I think I would prefer the bare PCB, but if you assemble some I will probably buy one of those, preferably with the screen.


I now have a slightly playable version of Pacman:


Here is the fix that makes all three of my Nunchuks work, with a test program:

I have also added it to the Pacman game.

There seem to be other differences in fake Nunchuks. They do not need to need the initial 0x40 ox00 to start woiking, which means you can unplug them and plug them back in. If I do that with the genuine Nintendo device it stops working.

Also, stangely the button mapping seems to be different with this fix. I used to press the large button to get a value of 0 and start a game. I now have to press both buttons, and that seems to be the same of fake and genuine devices.

Anyway, it all works on both types of Nunchuks for me now.


For what it’s worth, I’ve been working on a minimal USB host controller which can be used by PicoSoC

Any chance you could start another thread with this when it’s ready? I’m very interested for some other ideas!!



My only comment would be given it’s supposed to be a portable machine, does the audio need buffering and/or a volume control? eg. so it can be used “safely” with headphones?

You could put me down for a full assembled one though. I guess that means I’m going to need to order another TinyFPGA too! :slight_smile:



Anyway, it all works on both types of Nunchuks for me now.

Brilliant!!! Thank you!! Confirmed as working here too! :star_struck:

This is very, very cool to see it coming along… I just played a game and managed to collect all the pac-dots … :smiley: :smiley: :smiley:


i try to keep things as simple as possible, but I can put a small headphone amp like the LM4910. Can the volume be controlled from the SOC?


Can the volume be controlled from the SOC?

I think so, yes. Either by adding a global volume register to the audio output, or by scaling the channel volumes appropriately. I think between those two I prefer the global volume register option (to limit the work that the CPU has to do), but if I add a global volume register I’ll have to try and do it by reusing the multiplier used for the per-channel volumes, since space is tight :). The downside of doing this in digital space is that we’ll lose resolution at lower volumes, but ¯\(ツ)/¯ …

One other possibility is something like this: http://www.ti.com/lit/ds/symlink/tpa6140a2.pdf - it seems about the same price as the 4910, but has an I2C volume control built in. Downside is considerably more complexity, and I guess I2C may end up being a luxury that we don’t have space for anyway.

I do like the idea of adding an audio amp though. It means that the decoupling caps can be reduced in size, and we won’t end up losing anywhere near as much bass response as we would if we tried to drive the headphones directly …



I’ve added a global volume register to the audio side of things now, so that’s one less thing to worry about :slight_smile:



This Wii controller works with the Pacman game unchanged, but it needs some configuration as the button and joystick values are different. It has 11 buttons, a Dpad and two joy sticks, so should cope with most games.

I think my grandson got it for playing GoldenEye. 007.


If you use the Nintendo SNES Classic controller, you need to initialise it with:

i2c_write(0xf0, 0x55);


i2c_write(0xfb, 0x00;

(Instead of i2c_write(0x40, 0x00)).

It has 12 buttons including the Dpad, and they are in the last 2 of the 6 bytes returned by the device, so games will need changing slightly to use it.

I think all the Nintendo controllers will use one of these two initialisation sequences, and they all return 6 bytes of data.

I might implement dip switches, in the style of classic arcade game machines, to choose which controller to use for my Pacman game, so two dip switches could select Wii Nunchuk, Wii professional controller, SNES Classic, or button input.

I suspect that it is about time to start new topics for this stuff, perhaps one for the portable console, one for the VGA consoie, and one for Game development.


It sounds like your poor grandson is losing all of his toys to your lab :joy:


Don’t worry about him. He has now moved on to a Nintendo Switch :grinning:


I have @Fabien’s portable version working now with the 8-bit parallel ili9341 TFT LCD interface. One thing that threw me for a while is that the documentation for the BuyDisplay EasytRising LCD calls the 8 data pins DB0, DB1 … etc. and the pins.pcf file called them lcd_D0, lcd_D1 … , but the numbering is in the opposite direction with DB0 connected to lcd_D7 :confused:

I bought the 4-pin SPI version of the LCD first and have that working with my BlackIce II Ice40 FPGA, so it should not be hard to make it work with the BX. However it will probably be too slow for this as I doubt if it will do even 20fps.

The only difference between the variants of the displays is jumpers with solder bridges, so I could convert it to an 8-bit interface.

I am going to look next at merging Fabien’s work with the latest version of @gundy’s and mine and get Pacman and my platformer demo working on it.


That’s great!

Yeah I noticed that afterwards, I guess that’s the good thing about FPGAs, these kind of mistakes are not hard to solve :slight_smile:.

The LCD screen is refreshing at 50Hz. It would be best to be able to send the entire frame faster than that so we avoid the tearing effect. This requires sending the bytes at more than 10Mhz. So far I didn’t achieve this speed, my FPGA/Verilog knowledge is limited.

Update on the prototype board, I have received the components and the PCBs should be here this week (fingers crossed).


Hi @Fabien, I am struggling to get your ili9341 working reliably.

The first problem is that it does not start up reliably. That seems to be because you are only setting nreset for one clock cycle. I added a delay_ticks of ms5 to the RESET state, and that seems to have fixed that.

Another problem is the colours. The initialisation sequence includes 0x36 (MADCTL) 08, which sets the colour mapping to BGR. You had set colours in RGB order, so I reversed those. Also you were setting the G value to 5 bits, not six when it was set (6’b11111 not 6.b111111) which messed up colours with green in them. So I fixed that. I have left it as BGR.

There is also the problem that the image is horizontally and (at least with my screen orientation) vertically flipped, so I I am changing things. so that xpos and ypos count down.

I also found a problem in @gundy’s top.v module that stopped buttons working when i2c was not defined, so it now sets i2c_iomem_ready to i2c_en not 1, when i2c is not defined and similarly for gpio, and that fixed that problem, so I can now use button input without having to include the i2c code.

The final (I hope) problem is that it appears to sending each 16-bit pixel twice, so that the screen is stretched vertically and you only see half of it. I am currently trying to understand the complex interaction between all the state variables to try to see what is going on., and will look at what the maximum rate that we can send data at, at the same time.