SPI Hifive 1 Rev B


Sorry, I posted somewhat outdated link. Here is the correct one: https://github.com/espressif/esp-at/blob/ca5c45177574aef909e749b0c95dd84b188a8ec9/main/interface/hspi/at_hspi_task.c

0x41 byte: https://github.com/espressif/esp-at/blob/ca5c45177574aef909e749b0c95dd84b188a8ec9/main/interface/hspi/at_hspi_task.c#L348-L350

0x42 byte: https://github.com/espressif/esp-at/blob/ca5c45177574aef909e749b0c95dd84b188a8ec9/main/interface/hspi/at_hspi_task.c#L314

You can also see a HiFive1 example here: https://github.com/riscv-rust/riscv-rust-quickstart/blob/5ff7048687e807b52d3df0d05dd0729a7c52bf79/examples/spi_wifi.rs#L61-L91


Ah, this helps greatly. I will make my assembly code follow the Rust example. The github “download as ZIP” button kept giving me an older version that did not have the “A” “B” stuff in it.


I created a HiFive1 Rev B WiFi example here: https://github.com/kjarvel/hifive1revb_wifi


  • The code is generic C, using the registers from the Freedom E310-G002 Manual, not using the metal library.
  • The modules are sort of stand-alone, include cpu.h or uart.h to use them (except spi.c that requires all the others).
  • The code is sort of test code with no error handling, just to be simple (please be kind :wink: ).

The application enables 320 Mhz clock speed for the CPU, and 115200 bps for UART.
SPI1 communication speed is set to 80 kHz (can be changed).

Connect to the UART using for example Tera Term or PuTTY, enter the SSID and password of the AP you want to connect to, see the screenshot here:
(Press the reset button on the board until you see the initial AT+CWMODE=0-->OK message).

After disconnecting, you can enter extra AT commands.

To get this working:

  • Thanks to @Disasm for all the helpful hints!
  • I used a logic analyzer to get this to work, looking at the AT+CWMODE=0 commands sent by the default firmware (hifive_revb_bootloader).
  • The trick was to enable SPI1_CSMODE = CS_AUTO and SPI1_CSID = 2 to get the CS pin high / low.
  • Listening on the Handshake pin was also important…
  • Note that the code ignores any replies from the ESP32 (and does not ask for replies).

Hifive 1 Rev B interfacing with ESP32-SOLO-1

Why is this post flagged and hidden “by the community” ?

(Jim Wilson) #25

We have trouble with spammers trying to use our site for SEO by posting off-topic messages with URLs. So if someone registers, and quickly sends a bunch of messages with URLs, then they all get marked as possible spam by a script until an administrator looks at them. I unhid them.


One comment on this: the bootloader sets CSMODE to HOLD and changes it to AUTO right after writing the last byte. Also it doesn’t use SPI FIFO, instead it reads a byte after each write.
Setting mode to AUTO earlier leads to quite a strange CS glitches, at least on my board.


OK, I tried to find the source code for the default bootloader/firmware, but I was not able to find it, is it available somewhere?.

When I tried with HOLD mode, the CS pin never de-asserts, even after changing the value of csmode or csid as the manual says. I also tried to configure the CS pin as a normal GPIO pin and asserting/deasserting it manually, but I couldn’t get that to work at all.

But, I also just write one byte, read one byte on SPI, for example like this, and that seems to work:

for (uint32_t i = 0; i < 4; i++) {
        while (SPI1_TXDATA > 0xFF) {} // full bit set, wait
        SPI1_TXDATA = at_flag_buf[i];

That was pure luck I guess… finally it started to work well after checking the handhake line.


I do not have the source code, I reverse-engineered this with IDA Pro from the ELF file provided by SiFive in one of the forum threads.

I don’t know why it doesn’t work for you, but I currently switch from HOLD to AUTO after the last byte received and it works quite good. I do not switch after the last write because I utilize FIFOs and this early switch leads to the CS glitches.


If you want to try running without a bootloader (so to speak) you can try using my protector instead which does not touch anything but a specific PIN you can set up yourself.

I found a lot of funky stuff happening if I use the bootloader with PMU for example (backup register clobbering) so I just stopped using it. It’s also faster with no wait on reboot :slight_smile: