tinygo-org / tinygo

Go compiler for small places. Microcontrollers, WebAssembly (WASM/WASI), and command-line tools. Based on LLVM.
https://tinygo.org
Other
15.17k stars 890 forks source link

PIO Support for Raspberry Pi Pico #2589

Open bmentink opened 2 years ago

bmentink commented 2 years ago

Hi, Is there any support for the programmable IO module on the Pico? If not, will it be added at some point. Also, can not find how to do interrupts on GPIO's or ADC etc etc No idea howto print messages to the USB/Serial port either with printf ..

Maybe a list of what works and what is TODO would be great ..... I can see a lot of projects for this board and TinyGO

Many Thanks in advance ..

deadprogram commented 2 years ago

Please see https://github.com/tinygo-org/tinygo/issues/1953 regarding PIO.

bmentink commented 2 years ago

Thanks, so WIP ... good to see ..

Any idea how to see "println" messages on the pico?

EDIT: Never mind, sniffed around with the scope and found it on GPIO_0/1, I have attached an HC-05 bluetooth module, and can see the println's just fine ... I found the baud rate was 115200 by trial and error ..

sgall17a commented 1 year ago

I am a complete newbie in Tinygo and apologise for being so presumptive since I don't really know what I am talking about but here goes anyway.

The rp2 library in Micropython uses a simple method for assembling the pio instructions. pythonfunction(parameters)[waitstates] In PIO all instructions, parameters and wait states are packed into one 32bit word.

  1. The python function corresponds to the instruction bits.

  2. The parameter for the function builds the next few "parameter" bits.

  3. The square brackets indicate an "attribute" in python and build the (optional) wait bits. The function returns a python object and this can optionally have attributes to indicate wait values. There are a few rules limiting the maximum number of wait states which can vary by instruction (and ?globally for the statemachine I think).

  4. "label" is also a python function which can manage the PC.

The assembled PIO program would end up as a slice of 32bit words.

Converting the Python to GO could be done fairly easily ( I think).
Gluing it into Go could be harder (especially since I dont know much about Go internals). What I think you would need are (mostly housekeeping):

  1. Some way of poking the go array into the PIO memory.
  2. Some way of setting the control registrars so we can have more than one PIO program and communicate with the PIO.
  3. Some way of talking to the PIO FIFO's. Go channels would seem to be great way to do that for both receive and transmit channels.
  4. Some way of inserting an external execute instruction. This is just a register write.
  5. Some way to start and stop the state machine. This is just a register write.

Python uses a Statemachine object to manage the housekeeping. Presumably it calls the the C procedures documented in for Pi Pico to do this but the deeper internals of Micropython are beyond me.

As a new comer to Go I find putting assembler etc into comments deeply weird and I feel it should be discouraged. Using the Python approach, assembler could be build in nice go statements and produce a nice Go array/slice. This could be managed by a bunch of "C" procedures or even as direct register writes (if this is easy to do in go)

[Assemble PIO] -> [GoArray]->[Manage setting up PIO state Machines in Go] -> [Read PIO-FIFO into channel, Write channel into OUTPUT FIFO]. Also start and stop PIO state machine and insert single instruction for immediate execution.

0pcom commented 1 month ago

This repo appears to support the pico's PIO : https://github.com/tinygo-org/pio

However, this is not mentioned in the documentation or as a supported interface https://tinygo.org/docs/reference/microcontrollers/pico/

It might be worthwhile to mention or link the tinygo-org/pio library in the documentation.