Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ZeptoForth on the Pico Ice #59

Open
PythonLinks opened this issue Aug 14, 2023 · 19 comments
Open

ZeptoForth on the Pico Ice #59

PythonLinks opened this issue Aug 14, 2023 · 19 comments

Comments

@PythonLinks
Copy link

The pico-ice is a small, low cost board with the Raspberry Pi Pico processor (RP2040) and a Lattice Semiconductor iCE40UP5K FPGA.

https://pico-ice.tinyvision.ai/

Today my attention turned towards ZeptoForth. There are two versions of Forth that run on the RP2040, ZeptoForth and MeCrisp. Zepto is MIT license, Mecrisp is GPL. I prefer MIT. Also reportedly Zepto is better with Wifi.

There are two different issues in getting ZeptoForth to run on the Pico Ice. One is getting it to run on the RP2040, and the other is getting it to run on the FPGA. Let us discuss one at a time.

Probably not hard to get it to run on the Pico Ice RP2040, the trick is to get it to do what is needed. In particular it needs to set the PLL clock for the FPGA, and if I want to talk to the FPGA over USB, it would be good if it passed the terminal session through to the FPGA.

Ideally I would love a zepto forth command to pass usb connection to the FPGA. That should be easy to do. What I do not yet know how to do is to get the FPGA to pass it back. There are 8 wires connecting the two, I could image one wire would send a command from the FPGA to the RP2040 to invoke an interrupt to reclaim the terminal.

Maybe if you have two Zepto Forth processors, there could be two wires driving two different interrupts, one for each of the Zepto Forth processes. (Are there only 2?)

Since I am focused on the FPGA side of things using the sister Upduino board,
https://tinyvision.ai/products/upduino-v3-1
I do not currently have the time to make Zepto run on the Pico Ice RP2040.

The more interesting issues is getting Zepto Forth to run on the FPGA. Really to get it to run on many FPGAs. I am busy building a 24 bit * 4 core Forth processor on the Upduino. Each will have 10.6K * 24 bits of single port memory, and pairs of processors will share 10Kbits of dual port memory for communication. I am doing this on top of the J1 and Mecrisp soft core processors. To get Zepto running on the FPGA, I need to find the C program at the bottom of ZeptoForth and find out which words I would have to implement. Hopefully it uses the same ones that Mecrisp uses, that the J1 implements.

The other interesting issue is with the PIO interface. I need to do something similar. I wonder if PIO is patented?

In any case I have a lot of reading to do about ZeptoForth.

And thanks to Travis Bemann for mentioning Zepto to me. One has to hear about something several times to notice it. So that helped me notice you. Now I am most interested.

I live in Katowice Poland, and will be speaking at FPGA world in Stockholm on September 12th, if anyone is in this corner of the world.

@tabemann
Copy link
Owner

tabemann commented Aug 14, 2023

zeptoforth currently does not have actually working WiFi support, but it is in the works ─ I still have to get the bugs out before it will be ready for usage.

Running two tasks, one on each core (yes, there are two cores on the RP2040), is definitely a good idea, I must say.

Getting zeptoforth to run on an FPGA would require an ARM Cortex-M0+/M4/M7 soft core, as it by itself does not and will not run on FPGA's. This is unlike the J1 and Mecrisp Ice, which are specifically designed to run directly on FPGA's.

About there being a C program at the bottom of zeptoforth, there is no such thing ─ the zeptoforth kernel is written in ARMv6-M (for the M0+) and ARMv7-M (for the M4 and M7) assembly which runs directly on the hardware.

About IP issues with the PIO, I am not a lawyer, but channel controllers go back decades, and the PIO is essentially a channel controller, so what patents there were may very well have lapsed.

I'll say more later, but I've got to go off to work.

Travis Bemann

@PythonLinks
Copy link
Author

About there being a C program at the bottom of zeptoforth, there is no such thing.

Presumably your assembly supports a list of words. I fI implement those words, the rest should run fine. Where do I find that list of words?

I read more about ZeptoForth. Multitasking and sending messages to tasks looks very much based on Communicating Sequential Processes. That is what I am trying to achieve. Very nice. Most impressive.

@tabemann
Copy link
Owner

Presumably your assembly supports a list of words. I fI implement those words, the rest should run fine. Where do I find that list of words?

It is not that simple, because some of the most time-critical code in zeptoforth outside the kernel irself is written in assembly, for the sake of performance (and fitting inside the RP2040's 16K XIP cache).

As for lists of words, I have incomplete lists of words in the documentation, but for a complete list of words in the kernel itself I would grep all the *.s files in the relevant src directorie(s) for define_word and define_internal_word.

I read more about ZeptoForth. Multitasking and sending messages to tasks looks very much based on Communicating Sequential Processes. That is what I am trying to achieve. Very nice. Most impressive.

Yeah, that is what I intended when I implemented it.

@PythonLinks
Copy link
Author

I believe in your documentation, you said that if I send you a board, you would do the port. There are a bunch of us interested in Zepto Forth on the pico-ice, both some forth guys, and some guys who want a REPL, and some guys who just want another language besides to run there. There are some 600 of us on their discord server.

I am thinking we could do a crowd funding. If we sent you $50, would you do the port? How long would it take? Would it support USB pass through, and setting the FPGA's PLL?

https://pico-ice.readthedocs.io/_/downloads/en/latest/pdf/
Click on pico_ice_fpga

@josuah
Copy link

josuah commented Aug 17, 2023

@PythonLinks I wonder if PIO is patented?

I do not thing it is, it could be reproduced on an FPGA there https://github.com/lawrie/fpga_pio

@PythonLinks https://pico-ice.readthedocs.io/_/downloads/en/latest/pdf/

Can I know where you found this link? It might have out of date information.
The first one you posted was the right one, and here is the same ice_fpga.h library you quoted:
https://pico-ice.tinyvision.ai/ice_fpga.html

Would it support USB pass through, and setting the FPGA's PLL?

These things are already more or less provided by the pico-ice-sdk:

If some different APIs are needed, feel free to ask!

@PythonLinks
Copy link
Author

I found that link from a qwant search.

I know that those functions are supported in C. I am interested in running ZeptoForth on the pico-ice, but only if it also supports those functions.

@josuah
Copy link

josuah commented Aug 17, 2023

Understood! So this means through this support code rather than the pico-sdk:
https://github.com/tabemann/zeptoforth/blob/master/src/rp2040/forth/usb.fs

Kudos to @tabemann for implementing a device-side USB stack!

@PythonLinks
Copy link
Author

It is not clear to me how this all works. I suspect that the RP2040 has software configuration as to what functionality goes to what pin. If that is the case, to port it, all we have to do is to edit the file, and look at the schematics, and connect the pins correctly?

Is that corrrect?

I am also not quite clear about that USB functionality. I presume that is the host mode. Can it support multiple usb peripherals or just one.

My interest lies in all the software and peripherals. To get a Diligent stereo microphone and earphone jack, is like $27 plus shipping and taxes. Plus I need an I2S ip in the FPGA. The raspberry pi and usb stuff should be less expensive.

@tabemann
Copy link
Owner

It is not clear to me how this all works. I suspect that the RP2040 has software configuration as to what functionality goes to what pin. If that is the case, to port it, all we have to do is to edit the file, and look at the schematics, and connect the pins correctly?

Is that corrrect?

Like most typical MCU's the RP2040 has what is known as alternate functions where individual pins can be tied to individual functions, but not every pin can have every function.

I am also not quite clear about that USB functionality. I presume that is the host mode. Can it support multiple usb peripherals or just one.

zeptoforth on the RP2040, as you have found, uses USB device mode, but the RP2040 can support USB host mode. Note, however, that this will negate support for the USB CDC console, which is a device-mode feature. I would have to look to see if it could suppot multiple peripherals when in USB host mode; it should be mentioned somewhere in the datasheet.

@tabemann
Copy link
Owner

Kudos to @tabemann for implementing a device-side USB stack!

Well, it is not a full stack, but rather just enough to have a USB CDC console.

@tabemann
Copy link
Owner

I found that link from a qwant search.

I know that those functions are supported in C. I am interested in running ZeptoForth on the pico-ice, but only if it also supports those functions.

I have not looked at the details, but I do not see any reason why zeptoforth could not be extended to support controlling the FPGA (but not running on it, which will never happen). At the moment, though, I am kind of tied up in implementing IP* for the Pico W (which I call zeptoIP), so if you want to see a port to the Pico-Ice there will be a delay even if I am sent a board.

* Yes, a lot of it is implemented, but I keep on finding minor issues that need resolving, such as one I found this morning, so I am not quite done yet.

@PythonLinks
Copy link
Author

Talking to one of the senior Pico-Ice engineers, we now think that everything should just work as is.

There is only 1 set of power and usb pins We should be able to flash the board and have it boot, and then edit everything from ZeptoForth. Even if there are multiple reset pin options, just turn the board off and reboot.



He is trying it in the near future. Wish us luck. 







Here is what then needs to be done in Forth.




First I should say that there are two flash memories, one for the rp2040, and one for the pga. And there are 8 wires which connect the two devices.


1. Configure FUNCSEL , , to match the pico-ice board. Maybe this is already okay.

  1. Enable multiple USB Devices, one for the RP2040, one for the FPGA. The data sheet says that multiple USB devices are supported. Awesome!

  2. Create the ZeptoForth Firmware to get flashed to the board. I understand that when the board is reset, the flashing can be done.

  3. Toggle the FPGA pins so that the FPGA can boot from the RP2040 flash drive as is done now.

  4. Extend the Forth USB source code. One USB device mode goes to the RP2040 zeptoforth, the other one goes to the fpga. There might be several things to try here, for instance a button to swap what the USB interface points at, or never directly talk to the other cores on the iCE40 with a REPL, but instead have a forth library to send them code.

  5. Connect to the 8 FPGA to RP2040 wires. UART? SPI? Maybe SPI is better because there can be more channels.

  6. Connect one RP2040 PLL to the USB, the other to the FPGA.

  7. Send an interrupt from the FPGA to the RP2040 to switch a sole CDC console between devices. And a way to go from RP2040 to FPGA.

@josuah
Copy link

josuah commented Aug 18, 2023

I did test Zeptoforth on both the custom pico-ice and on a RP2040 pico, but somehow could not get anything reacting on USB.

As an attachment is the firmware I tried to install from the git tag v1.0.2
zeptoforth.rp2040.uf2.zip

It is possible that something is wrong with my setup.
Would it be possible to get an .uf2 build from your end? This would allow me double-checking if it is due to hardware (maybe some different RP2040 revision?) or my toolchain (though, just assembler and linker and libgloss & friends)?

Thank you!

@tabemann
Copy link
Owner

I did test Zeptoforth on both the custom pico-ice and on a RP2040 pico, but somehow could not get anything reacting on USB.

As an attachment is the firmware I tried to install from the git tag v1.0.2 zeptoforth.rp2040.uf2.zip

It is possible that something is wrong with my setup. Would it be possible to get an .uf2 build from your end? This would allow me double-checking if it is due to hardware (maybe some different RP2040 revision?) or my toolchain (though, just assembler and linker and libgloss & friends)?

Thank you!

The simplest way to get zeptoforth working is to flash your board win BOOTSEL mode with the USB Mass Storage device interface with zeptoforth-1.0.2/bin/1.0.2/rp2040/zeptoforth_full_usb-1.0.2.uf2 for USB console or zeptoforth-1.0.2/bin/1.0.2/rp2040/zeptoforth_full-1.0.2.uf2 for serial console. These are pre-built builds that should work out of the box. Note that these are not included in the source code downloads from GitHub, and are only available in the binary builds which are associated with each release, which should be named zeptoforth-1.0.2.tar.gz. You can find this here.

However, if you want to create your own build (which I would recommend doing, because there are bugfixes in the master and devel branches that have not yet been incorporated into a build due to my being preoccupied with other matters such as working on zeptoIP), I would follow the following steps after git clone-ing the zeptoforth repository:

make clean
make VERSION=<your choice of versions>
make install VERSION=<same as above>

This will give you, amongst other things, a kernel UF2 file in bin/<your version>/rp2040/zeptoforth_kernel-<your version>.uf2. Note that this is very barebones, as it is only a kernel and nothing more. It is essentially useless by itself. You will want to put your device into BOOTSEL mode (i.e. holding down the BOOTSEL button while power-cycling your device) and flash that UF2 onto it by copying the UF2 into the USB Mass Storage device that appears once you have mounted it.

What you will want to do next is to create a usable USB build on top of that kernel. For that purpose I would not directly use utils/codeload3.py, as that will merely upload code to your board without generating a usable image you can flash again in the future. Instead, I would suggest executing the following from the zeptoforth base directory:

utils/make_uf2_image.sh <your version> rp2040 <your serial device> full_usb

This will both install a full USB build on your board, and it will also generate files including a bin/<your version>/rp2040/zeptoforth_full_usb-<your version>.uf2 which you can flash onto boards in the future rather than having to rebuild zeptoforth for each board you want to install it on. Also note that if you just want a serial console build without USB just replace full_usb with full above.

@josuah
Copy link

josuah commented Aug 19, 2023

This is silly, this was all described properly in the README.

Prebuilt binaries are in bin/// in release tarballs. They are not included in source code-only zips or tarballs, or in the git repository.

My bad for assuming without looking. And thank you for your very detailed description.

@josuah
Copy link

josuah commented Aug 19, 2023

Of course after reading the documentation properly it works! I knew it was something off with what I did...

Welcome to zeptoforth
Built for rp2040, version 1.0.2, on Sat Jun 10 05:07:21 PM CDT 2023
zeptoforth comes with ABSOLUTELY NO WARRANTY: for details type `license'
 ok

Thank you for the quality of the documentation. No idea how I could gloss over it.

@pkoning2
Copy link

pkoning2 commented Dec 7, 2023

@PythonLinks I wonder if PIO is patented?

I do not thing it is, it could be reproduced on an FPGA there https://github.com/lawrie/fpga_pio

Nice piece of work, but the existence of that implementation tells us nothing about patents, if any, on PIO. If you need to know, the best option is probably to talk to a patent attorney.

@pkoning2
Copy link

pkoning2 commented Dec 7, 2023

On host mode and multiple devices, I remember seeing the statement that TinyUSB handles hubs, so one would assume the answer is that yes, it works. I see a host mode example in the SDK source tree, which handles both keyboard and mouse devices, but it's not completely obvious if or how it handles both of them being active at the same time. It should be easy enough to try that, though.

@tabemann
Copy link
Owner

tabemann commented Dec 8, 2023

Currently USB on zeptoforth only supports acting as a USB CDC console; being able to act as a host would require a substantial reworking of it, and furthermore would likely make being able to act as a USB CDC console infeasible (so if you want a console you would have to use seriall).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants