1 /* SPI Slave example, receiver (uses SPI Slave driver to communicate with sender)
3 This example code is in the Public Domain (or CC0 licensed, at your option.)
5 Unless required by applicable law or agreed to in writing, this
6 software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
7 CONDITIONS OF ANY KIND, either express or implied.
14 #include "freertos/FreeRTOS.h"
15 #include "freertos/task.h"
16 #include "freertos/semphr.h"
17 #include "freertos/queue.h"
19 #include "lwip/sockets.h"
21 #include "lwip/netdb.h"
22 #include "lwip/igmp.h"
25 #include "esp_system.h"
26 #include "esp_event.h"
27 #include "esp_event_loop.h"
28 #include "nvs_flash.h"
29 #include "soc/rtc_periph.h"
30 #include "esp32/rom/cache.h"
31 #include "driver/spi_slave.h"
33 #include "esp_spi_flash.h"
34 #include "driver/gpio.h"
40 SPI receiver (slave) example.
42 This example is supposed to work together with the SPI sender. It uses the standard SPI pins (MISO, MOSI, SCLK, CS) to
43 transmit data over in a full-duplex fashion, that is, while the master puts data on the MOSI pin, the slave puts its own
46 This example uses one extra pin: GPIO_HANDSHAKE is used as a handshake pin. After a transmission has been set up and we're
47 ready to send/receive data, this code uses a callback to set the handshake pin high. The sender will detect this and start
48 sending a transaction. As soon as the transaction is done, the line gets set low again.
52 Pins in use. The SPI Master can use the GPIO mux, so feel free to change these if needed.
54 #define GPIO_HANDSHAKE 2
61 //Called after a transaction is queued and ready for pickup by master. We use this to set the handshake line high.
62 void my_post_setup_cb(spi_slave_transaction_t *trans) {
63 WRITE_PERI_REG(GPIO_OUT_W1TS_REG, (1<<GPIO_HANDSHAKE));
66 //Called after transaction is sent/received. We use this to set the handshake line low.
67 void my_post_trans_cb(spi_slave_transaction_t *trans) {
68 WRITE_PERI_REG(GPIO_OUT_W1TC_REG, (1<<GPIO_HANDSHAKE));
77 //Configuration for the SPI bus
78 spi_bus_config_t buscfg={
79 .mosi_io_num=GPIO_MOSI,
80 .miso_io_num=GPIO_MISO,
81 .sclk_io_num=GPIO_SCLK
84 //Configuration for the SPI slave interface
85 spi_slave_interface_config_t slvcfg={
87 .spics_io_num=GPIO_CS,
90 .post_setup_cb=my_post_setup_cb,
91 .post_trans_cb=my_post_trans_cb
94 //Configuration for the handshake line
95 gpio_config_t io_conf={
96 .intr_type=GPIO_INTR_DISABLE,
97 .mode=GPIO_MODE_OUTPUT,
98 .pin_bit_mask=(1<<GPIO_HANDSHAKE)
101 //Configure handshake line as output
102 gpio_config(&io_conf);
103 //Enable pull-ups on SPI lines so we don't detect rogue pulses when no master is connected.
104 gpio_set_pull_mode(GPIO_MOSI, GPIO_PULLUP_ONLY);
105 gpio_set_pull_mode(GPIO_SCLK, GPIO_PULLUP_ONLY);
106 gpio_set_pull_mode(GPIO_CS, GPIO_PULLUP_ONLY);
108 //Initialize SPI slave interface
109 ret=spi_slave_initialize(HSPI_HOST, &buscfg, &slvcfg, 1);
112 WORD_ALIGNED_ATTR char sendbuf[129]="";
113 WORD_ALIGNED_ATTR char recvbuf[129]="";
114 memset(recvbuf, 0, 33);
115 spi_slave_transaction_t t;
116 memset(&t, 0, sizeof(t));
119 //Clear receive buffer, set send buffer to something sane
120 memset(recvbuf, 0xA5, 129);
121 sprintf(sendbuf, "This is the receiver, sending data for transmission number %04d.", n);
123 //Set up a transaction of 128 bytes to send/receive
127 /* This call enables the SPI slave interface to send/receive to the sendbuf and recvbuf. The transaction is
128 initialized by the SPI master, however, so it will not actually happen until the master starts a hardware transaction
129 by pulling CS low and pulsing the clock etc. In this specific example, we use the handshake line, pulled up by the
130 .post_setup_cb callback that is called as soon as a transaction is ready, to let the master know it is free to transfer
133 ret=spi_slave_transmit(HSPI_HOST, &t, portMAX_DELAY);
135 //spi_slave_transmit does not return until the master has done a transmission, so by here we have sent our data and
136 //received data from the master. Print it.
137 printf("Received: %s\n", recvbuf);