Documentation on this board is too sparse. For the average hobbyist it’s too cryptic to figure many things out. It took me several hours to get everything set up and I still don’t understand how to get wifi working. Are there any instructions or examples I can look up? All I found was this: https://github.com/sifive/riscv-zephyr/tree/hifive1-revb/drivers/wifi and this: Hifive1 revb WiFi
But these are ridiculously complex. Shouldn’t there just be a Wifi library?
Another thing I can’t figure out is how to get/set the clock speed. There’s metal_clock, but it’s totally unclear how I’m actually supposed to use it. This is the doc: ht tps://sifive.github.io/freedom-metal-docs/apiref/clock.html#structmetal__clock (This forum has a restriction for new users to only add two links into a post)
All the functions require a metal_clock, but the doc explicitly says:
Note that no mechanism for obtaining a pointer to a struct metal_clock has been defined, making it impossible to call any of these functions without invoking implementation-defined behavior.
What does that mean? I found no usage example of this, even though IMO this is a very basic functionality, considering this board was advertised as having a fast and low power chip, and as having wifi.
One more thing I can’t wrap my head around is why Rev. B has dropped support for the Arduino IDE which would have been much more user friendly than “FreedomStudio”. This wasn’t advertised anywhere except for some small note in chapter 7 or so of the getting started guide. The naming of Rev. B itself is also misleading, causing people to think that it’s going to be at least mostly compatible with the first one, but in fact a lot of the documentation for the first version is now obsolete - sifive should’ve called this hifive2 or something, to avoid confusion and make googling things easier.
Rev B is quite compatible with the first version. In the Rust support library we even use the same SVD file for both FE310-G000 and FE310-G002 chips. If you are familiar with Rust, I’d recommend you to give it a try. There is a quickstart project with some examples.
I had the same problem and I’m still not sure how to configure the PLL with the Metal library.
However I RTFM and I came up with the following code which seems to work for me:
My experience was that it is a lot easier to just read the FE350-G002 specs and write the clock code in assembly, rather than try to figure out what the ‘metal’ library was trying to be clever about.
Here is the entireity of my clock speed setting code.
# PRCI holds the CPU timing controls
.equ P_BASE, 0x10008000
.equ P_HFROSCCFG , 0x00 # Ring osc config
.equ P_HFXOSCCFG , 0x04 # XTAL osc config
.equ P_PLLCFG , 0x08 # PLL config
.equ P_PLLDIV , 0x0C
.equ P_PROCMONCFG , 0xF0
.equ PLLSEL, 1<<16 # PLL selected as clock source
.equ PLLREFSEL, 1<<17 # PLL to take XTAL as reference
.equ PLLBYPASS, 1<<18 # PLL bypassed and shut off
.text
# Initialize all timing functions. We start out on the Ring oscillator
# but need to use the XTAL instead, through the Phase-locked Loop.
.global cinit
cinit:
# Make sure XTAL osc is stable so we can depend on it.
li t0, P_BASE
1: lw t1, P_HFXOSCCFG(t0)
bgtz t1, 1b
# Set PLL configuration for 64 MHz but do not select it yet.
li t1, 0x20DF1
sw t1, P_PLLCFG(t0)
# Wait for PLL to lock, indicated in sign bit
2: lw t1, P_PLLCFG(t0)
bgtz t1, 2b
# Ok now to select the PLL as the clock source.
li t1, 0x30DF1
sw t1, P_PLLCFG(t0)
ret
Thanks, looks disgusting but I’ll give it a try. I’ll also have a look at the Rust lib, but I still think there should be a simple way to do this in C, since it’s the official language.
Yeah I find C is harder to work with when it comes to this board than Rust. The rust guys did a great job writing nice and functional abstractions. I find metal completely useless and extremely hard to follow (seen the vtable mess?)