Getting tinygo to work with Blinks

So, one of the things I wanted to do with blinks is provide an alternative way of developing for it. I am a big fan of Go so I decided to, no pun intended, give it a go.

It turns out there is a project to use go to write code for micro-controllers and it does support Arduino/AVR:

I am literally at the very beginning and I started writing the required code for the atmega168pb (this is the correct chip for Blinks, right?). The first step is to write the code to map pin numbers to hardware registers. As a reference, here is the code for the atmega328p (which is most likely the closest supported machine to the atmega128pb):

Is anyone aware of any documentation that would point to this mapping in the case of the 168p? Maybe @bigjosh?

FYI, code generated with tinygo would be similar in size of equivalent C code. Due to memory and storage limitations, we would not be able to use goroutines (for concurrency, which is really not needed in the context of a Blink). We can also fully disable the garbage collector and the compiler is smart enough to tell us if we are doing something that would need it. The main advantage is most likely what I consider a nicer syntax without the cost of C++.

I am a big fan of Go so I decided to, no pun intended, give it a go.

Go on blinks would be very cool!

the atmega168pb (this is the correct chip for Blinks, right?

Correct, same as on the original Uno so a very well supported chip. It should also be functionally identical to the atmeag328p for anything a blinks user program would want to do.

The first step is to write the code to map pin numbers to hardware registers.

So there are a few ways you could do this depending on what level you want to work at (and how much work you want to do - lower levels=more work!)…

  1. Run bare metal. Here you talk directly to the hardware and your code is the only thing running on this blink.
  2. Run on top of the blinkBIOS. In this case, you would talk to the bios which would handle all the sensitive timing and hardware interaction for you. This gives you a lot of control with the downside that you are responsible for for more.
  3. Run on top of the blinkBIOS. In this case, you would basically just be writing a normal blinklib-based game except your setup() and loop() (and anything they called) would be in go.

Normally I’d say #3 is the best place to be for most people, but I actually think you might be very happy at #2 since then you could implement your own programming model as an alternative to the highly opinionated state-based bliknlib model. You could, for example, directly send and process asynchronous IR packets.

If you pick #2 then you should not need to touch the hardware directly. Instead you can use the services provided by the blinkBIOS to interact with things like the LEDs, button, and IR links. This should greatly simplify things since a user program need only to be able to read/write to the bios data structures and also call the bios function vectors. Probably the hardest part will be getting the kinks worked out of the toolchains so that the go compiler and linker can produce the right output files in the right places.

The bios API is defined in these files…

Once you have that working, then you should be able to blink leds and send IR packets. Still lots more work to do to have a practical base for real games, but also lots of opportunities to make opinionated decisions on how things should be best designed.

Does #2 sound like a path you’d like to give a try?

So, I need to start by adding specific machine support (i.e. atmega168pb support). When this is all done so I could potentially run bare metal but, of course, at this stage without any support for the nice LEDs (it seems there are some caveats with controlling them) and the IR transmitter/receiver.

TinyGo itself has some abstraction build in so I could potentially add support to the LEDs and IR and, at this point, it should be able to actually boot a blink and control things with a considerably low level API. In other words, I think this is a required step either way, even if not the final goal.

That makes perfect sense as a second step (again, even if not the end goal) because it would simplify things considerably. There is no precedent on TinyGo to do anything other than bare metal access, but it is not impossible as it can actually call C functions without problems (I guess we would need some of the linker magic to get things to work here).

I think you mean BlinkLib, not BlinkBIOS, right? :slight_smile: I guess I should check if this is feasible because, for obvious reasons, this would simplify things a lot and, in the end, what I want is to be able to write games using Go.

Ahahahahha… Don’t get me wrong, I am not fundamentally against how blinklib does things. Our discussion about datagrams started simply because I wanted an error reported back in a specific case. I did not need a complete rewrite of everything. :slight_smile:

I agree this is the most tempting one, but because it is a middle ground between 1 and 3 and because 1 is how TinyGo usually does things and 3 is not something that was ever done using it, It night not be worth if 3 is feasible. And if 3 is unfeasible, 2 is likely also unfeasible (by unfeasible I mean not how things are supposed to be done. This is all software in the end and we can do pretty much anything).

Thanks, this is useful. Just out of curiosity, is the actual BlinkBIOS code closed-source? I searched and could not find it. I am not against closed-source code in principle. It is just that if the code is available, it would probably simplifythe wokr I am doing. :slight_smile:

I will give this some consideration and will let you know. Thanks for all insights.