# SPI Hifive 1 Rev B

**URL:** <https://forums.sifive.com/t/spi-hifive-1-rev-b/2666>\
**Category:** HiFive1 Rev B\
**Created:** [July 24, 2019, 6:10am UTC](https://forums.sifive.com/t/spi-hifive-1-rev-b/2666 "2019-07-24T06:10:09Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![hrishikesh](https://avatars.discourse-cdn.com/v4/letter/h/d26b3c/32.png) [@hrishikesh](https://forums.sifive.com/u/hrishikesh)\
**Post date:** [July 24, 2019, 6:10am UTC](https://forums.sifive.com/t/spi-hifive-1-rev-b/2666/1 "2019-07-24T06:10:09Z")

</div>

I am working with the Hifive 1 rev B, the main aim is to communicate with the ESP32 Chip on the Board using SPI. The example code that is available with the Freedom e SDK, is not working for me. I tried to debug the code and it seems stuck in a loop. How do i setup a working demo of SPI on Hifive 1B?  
I just started working with the Borad, this is completely new for me. so please advice.

---

<div class="post-metadata">

**Author:** ![Bumbieris112](https://sea2.discourse-cdn.com/flex020/user_avatar/forums.sifive.com/bumbieris112/32/665_2.png) [@Bumbieris112](https://forums.sifive.com/u/Bumbieris112)\
**Post date:** [July 24, 2019, 4:36pm UTC](https://forums.sifive.com/t/spi-hifive-1-rev-b/2666/2 "2019-07-24T16:36:56Z")

</div>

I am also experiencing this issue. Program hangs on “metal\_spi\_transfer(spi, &config, 3, tx\_buf, rx\_buf);”.

If someone reading this is working in Sifive, please hire a human to maintain and make sample programs. The included samples have problems. At least finaly thanks for led blinking demo fix. And please, restore Arduino IDE support or at least software support like in Hifive1. My Hifive revb board is currently an expensive paper weight. I can’t do anything meaningful without software samples and libraries.

---

<div class="post-metadata">

**Author:** ![Disasm](https://sea2.discourse-cdn.com/flex020/user_avatar/forums.sifive.com/disasm/32/690_2.png) [@Disasm](https://forums.sifive.com/u/Disasm)\
**Post date:** [July 25, 2019, 10:13am UTC](https://forums.sifive.com/t/spi-hifive-1-rev-b/2666/3 "2019-07-25T10:13:12Z")

</div>

I’m not from SiFive, but in Rust community we do have working examples for this board: [https://github.com/riscv-rust/riscv-rust-quickstart/tree/master/examples](https://github.com/riscv-rust/riscv-rust-quickstart/tree/master/examples)  
Everyone is welcome to try this out 🙂  
If you are new to Rust, you can start [here](https://docs.rust-embedded.org/) or [here](https://www.rust-lang.org/learn).

---

<div class="post-metadata">

**Author:** ![penguinwashere](https://sea2.discourse-cdn.com/flex020/user_avatar/forums.sifive.com/penguinwashere/32/683_2.png) [@penguinwashere](https://forums.sifive.com/u/penguinwashere)\
**Post date:** [July 25, 2019, 10:27pm UTC](https://forums.sifive.com/t/spi-hifive-1-rev-b/2666/4 "2019-07-25T22:27:08Z")

</div>

I barely got any of the sifive examples to work. I use the rust stuff because it actually works and its pretty easy to get started.

---

<div class="post-metadata">

**Author:** ![akshaim](https://avatars.discourse-cdn.com/v4/letter/a/87869e/32.png) [@akshaim](https://forums.sifive.com/u/akshaim)\
**Post date:** [July 30, 2019, 11:50am UTC](https://forums.sifive.com/t/spi-hifive-1-rev-b/2666/5 "2019-07-30T11:50:19Z")

</div>

Can’t believe one has to learn a new programming language altogether to use a Microcontroller Board !!!

---

<div class="post-metadata">

**Author:** ![Disasm](https://sea2.discourse-cdn.com/flex020/user_avatar/forums.sifive.com/disasm/32/690_2.png) [@Disasm](https://forums.sifive.com/u/Disasm)\
**Post date:** [July 31, 2019, 11:48am UTC](https://forums.sifive.com/t/spi-hifive-1-rev-b/2666/6 "2019-07-31T11:48:19Z")

</div>

You do not have to. Rust is not forced or even officially supported by SiFive, it’s just a nice alternative.

---

<div class="post-metadata">

**Author:** ![arya](https://avatars.discourse-cdn.com/v4/letter/a/a4c791/32.png) [@arya](https://forums.sifive.com/u/arya)\
**Post date:** [August 1, 2019, 1:20pm UTC](https://forums.sifive.com/t/spi-hifive-1-rev-b/2666/7 "2019-08-01T13:20:44Z")

</div>

Hi I am also facing the same problem. Please provide some help.

---

<div class="post-metadata">

**Author:** ![marijnfs](https://avatars.discourse-cdn.com/v4/letter/m/97f17d/32.png) [@marijnfs](https://forums.sifive.com/u/marijnfs)\
**Post date:** [September 22, 2019, 1:06pm UTC](https://forums.sifive.com/t/spi-hifive-1-rev-b/2666/8 "2019-09-22T13:06:54Z")

</div>

Hi, I’m also trying to figure things out and can only find these threads. One step I figured out is that the default freedom-e-sdk repo clone ends up in an ‘old’ branch from May. In this branch only SPI(0) is available! You need to go to the bleeding edge such that you can spi = metal\_spi\_get\_device(1);  
From there I haven’t been able to get a sensible response yet from the ESP32, but I believe you need to send the characters ‘AT\r\n’ as an initial message.

---

<div class="post-metadata">

**Author:** ![Disasm](https://sea2.discourse-cdn.com/flex020/user_avatar/forums.sifive.com/disasm/32/690_2.png) [@Disasm](https://forums.sifive.com/u/Disasm)\
**Post date:** [September 23, 2019, 6:55am UTC](https://forums.sifive.com/t/spi-hifive-1-rev-b/2666/9 "2019-09-23T06:55:30Z")

</div>

> [@marijnfs](#):
>
> but I believe you need to send the characters ‘AT\r\n’ as an initial message.

I don’t think it’s mandatory. At the same time, I had some observations of WiFi module behavior and noticed that two things are mandatory:

1. CS to packet time should be small. This means that it’s better to use hardware-controlled CS)
2. Delay between bytes in packet should be avoided. This means that you should prepare your packet in advance and use SPI FIFO to prevent underflows.

Also remember that SPI communication with ESP32 uses its own protocol (not just sending character bytes back and force).

---

<div class="post-metadata">

**Author:** ![marijnfs](https://avatars.discourse-cdn.com/v4/letter/m/97f17d/32.png) [@marijnfs](https://forums.sifive.com/u/marijnfs)\
**Post date:** [September 23, 2019, 7:59am UTC](https://forums.sifive.com/t/spi-hifive-1-rev-b/2666/10 "2019-09-23T07:59:11Z")

</div>

Interesting indeed. Have you found the actual protocol description anywhere? I’ve tried to read the ESP slave driver code but I haven’t been able to figure it out. Somewhere I saw some code where first a _send_ or _revc_ byte is sent, then the size, and then the message. But that didn’t work for me.

---

<div class="post-metadata">

**Author:** ![Disasm](https://sea2.discourse-cdn.com/flex020/user_avatar/forums.sifive.com/disasm/32/690_2.png) [@Disasm](https://forums.sifive.com/u/Disasm)\
**Post date:** [September 23, 2019, 8:14am UTC](https://forums.sifive.com/t/spi-hifive-1-rev-b/2666/11 "2019-09-23T08:14:43Z")

</div>

I haven’t seen any protocol _description_, so I had to reverse-engineer it. In this protocol each `send` or `recv` is a 3-packet sequence (“I want to send/recv”, “data length is _y_”, “actual data”). ESP32 also uses “handshake” pin to signal its readiness.

---

<div class="post-metadata">

**Author:** ![marijnfs](https://avatars.discourse-cdn.com/v4/letter/m/97f17d/32.png) [@marijnfs](https://forums.sifive.com/u/marijnfs)\
**Post date:** [September 23, 2019, 10:11am UTC](https://forums.sifive.com/t/spi-hifive-1-rev-b/2666/12 "2019-09-23T10:11:17Z")

</div>

Thanks, did you figure out in more detail? Are they first two packets indeed 4 bytes? And are they LSB?

I set gpio 10 to input (I believe that is the handshake pin), but I also believe pgio 9 is a chip enable pin? Do I need to turn that on as well?

Btw, I saw in the slave driver somewhere that only 512 byte packages were possible, which might result in the small packets you observed.

---

<div class="post-metadata">

**Author:** ![Disasm](https://sea2.discourse-cdn.com/flex020/user_avatar/forums.sifive.com/disasm/32/690_2.png) [@Disasm](https://forums.sifive.com/u/Disasm)\
**Post date:** [September 23, 2019, 8:27pm UTC](https://forums.sifive.com/t/spi-hifive-1-rev-b/2666/13 "2019-09-23T20:27:36Z")

</div>

I used a logic analyzer to analyze packet exchange during the boot stage (bootloader talks to ESP32 4 times or so). First two packets contain exactly 4 bytes. First packet is `01 00 00 00` (for recv) or `02 00 00 00` (for send). The second packet contains data size to transfer (in little endian): `XX 00 00 41` for send and `XX 00 00 42` for recv. The third packet contains actual bytes and nothing else.  
Note that SPI performs data transfer in both directions at the same time, so, for example, if you want to receive data size packet from ESP32, you also have to send 4 bytes of garbage. The same for the last packet.

---

<div class="post-metadata">

**Author:** ![marijnfs](https://avatars.discourse-cdn.com/v4/letter/m/97f17d/32.png) [@marijnfs](https://forums.sifive.com/u/marijnfs)\
**Post date:** [September 24, 2019, 8:46pm UTC](https://forums.sifive.com/t/spi-hifive-1-rev-b/2666/14 "2019-09-24T20:46:03Z")

</div>

Thanks so much for the info. I’m trying to apply it but still not sure about some things. In the read response, who writes the values? Is the slave supposed to reply with 02 … etc? I tried to use this approach but no success yet: [https://gist.github.com/marijnfs/61af97c2ecdd9b1076486bcaa513051a](https://gist.github.com/marijnfs/61af97c2ecdd9b1076486bcaa513051a)

---

<div class="post-metadata">

**Author:** ![Disasm](https://sea2.discourse-cdn.com/flex020/user_avatar/forums.sifive.com/disasm/32/690_2.png) [@Disasm](https://forums.sifive.com/u/Disasm)\
**Post date:** [October 8, 2019, 10:22am UTC](https://forums.sifive.com/t/spi-hifive-1-rev-b/2666/15 "2019-10-08T10:22:09Z")

</div>

I believe this `printf` can break timings, which are important here:

> <https://gist.github.com/marijnfs/61af97c2ecdd9b1076486bcaa513051a#file-test-cc-L34>

1. for reading data you should send 01 00 00 00 command, not 02 00 00 00
2. In the second packet you will receive the length of the data available. You should use it for the third packet (send N zero bytes, receive N data bytes).

---

<div class="post-metadata">

**Author:** ![marijnfs](https://avatars.discourse-cdn.com/v4/letter/m/97f17d/32.png) [@marijnfs](https://forums.sifive.com/u/marijnfs)\
**Post date:** [October 9, 2019, 6:45pm UTC](https://forums.sifive.com/t/spi-hifive-1-rev-b/2666/16 "2019-10-09T18:45:57Z")

</div>

Thanks, good idea. However removing printf doesn’t seem to help. There seems to be some more disccusion here: [HiFive1 Rev. B - How to use Wifi? How to get/set CPU clock speed?](http://forums.sifive.com/t/hifive1-rev-b-how-to-use-wifi-how-to-get-set-cpu-clock-speed/2902)

---

<div class="post-metadata">

**Author:** ![LightBulb](https://sea2.discourse-cdn.com/flex020/user_avatar/forums.sifive.com/lightbulb/32/693_2.png) [@LightBulb](https://forums.sifive.com/u/LightBulb)\
**Post date:** [October 22, 2019, 2:26pm UTC](https://forums.sifive.com/t/spi-hifive-1-rev-b/2666/17 "2019-10-22T14:26:24Z")

</div>

So this handshake protocol carries the AT command strings as its payload? I suppose that it is not guaranteed that each data packet contains exactly one AT commnd…

---

<div class="post-metadata">

**Author:** ![LightBulb](https://sea2.discourse-cdn.com/flex020/user_avatar/forums.sifive.com/lightbulb/32/693_2.png) [@LightBulb](https://forums.sifive.com/u/LightBulb)\
**Post date:** [October 23, 2019, 5:52pm UTC](https://forums.sifive.com/t/spi-hifive-1-rev-b/2666/18 "2019-10-23T17:52:47Z")

</div>

In that code, after the AT string has been sent, there are another two more SPI operations that do a ‘send’ of zero bytes. Is that a necessary part of the protocol to indicate that all of the data has been transfered?

The ping-pong nature of this exchange is part of how SPI works. But the SPI specification is just for a bidirectional bitstream - the format of the data is up to the device maker, in this case Espressif, the maker of the ESP32-SOLO-1. So far I have been unable to find this protocol documented, but am asking in the Espressif support forums.

---

<div class="post-metadata">

**Author:** ![Disasm](https://sea2.discourse-cdn.com/flex020/user_avatar/forums.sifive.com/disasm/32/690_2.png) [@Disasm](https://forums.sifive.com/u/Disasm)\
**Post date:** [October 23, 2019, 7:24pm UTC](https://forums.sifive.com/t/spi-hifive-1-rev-b/2666/19 "2019-10-23T19:24:19Z")

</div>

I believe that another two operations are first two packets of recv.

The relevant code on ESP32: [https://github.com/espressif/esp-at/blob/master/main/interface/hspi/at\_hspi\_task.c](https://github.com/espressif/esp-at/blob/master/main/interface/hspi/at_hspi_task.c) I used this to understand the protocol.

---

<div class="post-metadata">

**Author:** ![LightBulb](https://sea2.discourse-cdn.com/flex020/user_avatar/forums.sifive.com/lightbulb/32/693_2.png) [@LightBulb](https://forums.sifive.com/u/LightBulb)\
**Post date:** [October 27, 2019, 1:02pm UTC](https://forums.sifive.com/t/spi-hifive-1-rev-b/2666/20 "2019-10-27T13:02:33Z")

</div>

In esp-at-master/examples/at\_spi\_master\_for\_esp8266/main/app\_main.c I find these definitions:

```
/* SPI data cmd definition */
#define SPI_MASTER_WRITE_DATA_TO_SLAVE_CMD 2
#define SPI_MASTER_READ_DATA_FROM_SLAVE_CMD 3
 /* SPI status cmd definition */
#define SPI_MASTER_WRITE_STATUS_TO_SLAVE_CMD 1
#define SPI_MASTER_READ_STATUS_FROM_SLAVE_CMD 4

```

Close, but not quite what you are seeing. So far I have been unable to find code that actually generates the patterns you observe. For example, what is the purpose of the 0x41 and 0x42?

[Next page](https://forums.sifive.com/t/spi-hifive-1-rev-b/2666.md?page=2)
