40-fps 16-bpp platform game on a Cortex M0+ board

An ATSAMD21 (same as Arduino Zero) handles parallax scrolling, 16-bpp graphics at 40-fps on a 160x128 TFT LCD

Similar projects worth following
A poor's man hand-held console is made using a small Cortex M0+ board (Arduino Zero compatible), some switches, a widespread 1.8” 160x128 pixels TFT display and few other external components. In this project we focus on a platform game.

The framerate is fixed at 40 fps (without frame cap, the frame rate would vary between 41 and 51 fps), and the graphics engine can handle dual playfield with parallax scrolling, at 16bpp (65536 colors).
Some more optimization is still possible, without using assembly, which could lead to a better constant fps value.

The graphics engine can be used for many other types of games: racing game, shoot ‘em up, etc.

Sound samples and music (not yet implemented) will be stored on an SD card, which can be mounted on the SD card slot on the bottom side of the TFT module board.

In this example, the game graphics is from Sunny Land free game art from ansimuz (see links)


I wanted to see how far I could push the Cortex M0+ of the Arduino Zero. I think it is a balanced microcontroller: not too limited like an AVR, not too fancy, like a Cortex M4 (which has enough computing power even to run Doom).

I wanted to do something that could be challenging and, at the same time, funny. Well, I love 2D platform games. Why not starting from them?

Even if 2D platform games might seem outdated, they still require a good amount of memory, and if no hardware 2D acceleration is present, all the data must be processed by the CPU or, if present, by the DMA.

Initially I went on the conservative way: the ATSAMD21 specifies a maximum SPI frequency of about 12MHz, and by specification, the ST7735 controller allows a maximum SPI frequency of 15MHz (66ns SCLK time). Therefore I set the SPI frequency to 12 MHz and I also fixed the frame rate to 25 fps (without cap, the refresh frequency fluctuated from 28 to 33 Hz. I wanted to save a couple of fps because I will need to implement the sound later).

However I have recently realized that both the display and the ATSAMD21 can work at 24 MHz! That's a good overclock amount!  (still the CPU is not overclocked!)

Now, the uncapped frame rate goes up to 51 fps, and, with capping a constant 40-fps frame rate can be achieved!

Specifications achieved so far:

  • Resolution: 160 x 128 pixel
  • Color depth: 16 bpp
  • Dual playfield with parallax scrolling
  • Up to full-screen overlay for score/life
  • Multiple on-screen sprites.
  • Frame rate: minimum 40 fps using an out-of-spec 24 MHz SPI frequency value. Using a 12 MHz SPI, we can achieve more than 28 fps. 

The hardware:

The hardware is composed by three boards.

  • Then there is of course the TFT LCD. I chose a 1.8” SPI 160x128 TFT module, with SD card slot (which might be useful to store audio samples and music). The controller of that particular module is an ST7735. I verified that the ILI9341 modules work too, without software modifications. As you can see, by default they come without the right side header soldered on them. You must solder it.
  • And well, to play a game you’ll need some sort of input, something like a gamepad! I decided to implement a 8-key gamepad. These are placed on the carrier board, which hosts also few passive components and an 8-DIP IC, which is an operational amplifier for the earpieces. The op amp is connected to the 10-bit DAC output of the ATSAMD21.

The power can be provided either through the micro USB connector of uChip, or externally, for instance using 3 AA/AAA batteries. 

 The board layout and schematics will be available in KiCad format (a popular free PCB CAD program).

Preliminary considerations

Before jumping head-first into the project let’s make some rough estimations. Is it feasible?

Computing Power. Enough?

Yes, the ATSAMD21 is quite powerful. Enough powerful? It is a 48 MHz Cortex M0+, with a good DMA engine. Let’s make a ballpark calculations. The 48MHz frequency means that we have about 93 clock cycles per each pixel, at 25 fps....

Read more »

  • 1 × 1.8 " TFT Display (160x128) A very popular 1.8" TFT display already soldered on a PCB board. Very common on ebay and aliexpress
  • 1 × uChip A small Arduino Zero compatible board, which can be fitted in a 16-pin IC socket. Can be bought in
  • 1 × The carrier board This includes keys and few other components

View all 2 project logs

Enjoy this project?



Horst Schlawutzke wrote 05/20/2020 at 04:20 point


  Are you sure? yes | no

bobricius wrote 04/11/2019 at 21:23 point

Gamebuino Meta compatibility?

  Are you sure? yes | no

Nicola Wrachien wrote 04/12/2019 at 06:11 point


For sure it is not 100% compatible, because of the different signal wiring. I also think that the Gamebuino had the ATSAMD21G - i.e. the same CPU, but with more pins.

Moreover, the SD is for sure connected in a different way, even though I plan to make some changes and have the SD on a separate SPI bus on the next release.

Another incompatibility is the way I have routed the keys, to save on pin count - you can find all the details, sources, and KiCAD project on (see link on the left). 

All these incompatibilities, however, can be "fixed" by  modifying the source code, which is available on next-hack.

From the software viewpoint, I didn't use any framework/library: eveything, including the "graphics engine" was programmed from scratch. It can be easily adapted for other 2D games.

In other words, to play this game on Gamebuino, or to play Gamebuino games on this thing, you'll have to make some changes at the source level, but this is 100% feasible.

  Are you sure? yes | no

deʃhipu wrote 03/26/2019 at 14:51 point

Congratulations on a very nice game! I used some of the same tricks in #µGame, but unfortunately I couldn't use DMA, because of CircuitPython's lack of support for it. Still I'm getting a reasonable dozen frames per second, which is enough for the kind of games I'm interested in. Of course no scrolling and no parallax — that is actually pretty impressive in this project.

  Are you sure? yes | no

Sagar Shubham wrote 03/26/2019 at 13:31 point

Hey, nice project and a good application of DMA. Congrats. How did you get the ST7735 to work at 24 MHz? It seems to cap out at 15 MHz. 

  Are you sure? yes | no

Nicola Wrachien wrote 03/26/2019 at 13:42 point

Yes, the datasheet says that the clock cycle must be 66 ns (15 MHz). But I tried and it works :) Maybe the 15 MHz spec is way too conservative. Similarly, the ATSAMD21 should not be able to output a 24 MHz SPI signal, according to the datasheet. Still it works too :)

  Are you sure? yes | no

mehdi wrote 03/17/2019 at 08:32 point

Nice Job broo!!!

i hope you done soon

could you share code?

i interested about your idea to draw graphics object, i want see how :D


  Are you sure? yes | no

Nicola Wrachien wrote 03/20/2019 at 21:02 point

Yes very soon! After code clean-up and documentation! ;)

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates