ESP32 を SPI のスレーブとして使うサンプルです。
Raspberry Pi 4 をマスターとして、テストをしました。
プログラム
slave_calc.ino
// ---------------------------------------------------------------------
/*
slave_calc/slave_calc.ino
Jun/25/2025
*/
// ---------------------------------------------------------------------
#include "driver/spi_slave.h"
#include "driver/gpio.h"
#define PROGRAM "slave_calc.ino"
#define VERSION "2025-06-26 PM 13:40"
#define PIN_MOSI 23
#define PIN_MISO 19
#define PIN_SCLK 18
#define PIN_CS 5
uint8_t recv_buf[1];
uint8_t send_buf[1];
// ---------------------------------------------------------------------
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println("*** start ***");
Serial.println("SPI Slave init");
// SPIスレーブ設定
spi_slave_interface_config_t slave_config = {
.spics_io_num = PIN_CS,
.flags = 0,
.queue_size = 1,
.mode = 0,
.post_setup_cb = NULL,
.post_trans_cb = NULL
};
spi_slave_transaction_t t;
memset(&t, 0, sizeof(t));
// SPIピン設定
spi_bus_config_t bus_config = {
.mosi_io_num = PIN_MOSI,
.miso_io_num = PIN_MISO,
.sclk_io_num = PIN_SCLK,
.quadwp_io_num = -1,
.quadhd_io_num = -1,
.max_transfer_sz = 1
};
// バスとデバイス初期化
esp_err_t ret;
ret = spi_slave_initialize(HSPI_HOST, &bus_config, &slave_config, SPI_DMA_DISABLED);
assert(ret == ESP_OK);
delay(1000);
Serial.println(PROGRAM);
Serial.println(VERSION);
Serial.println("*** setup end ***");
}
// ---------------------------------------------------------------------
void loop() {
spi_slave_transaction_t t;
memset(&t, 0, sizeof(t));
t.length = 8; // 8 bits
t.rx_buffer = recv_buf;
t.tx_buffer = send_buf;
esp_err_t ret = spi_slave_transmit(HSPI_HOST, &t, portMAX_DELAY);
if (ret == ESP_OK) {
uint8_t received = recv_buf[0];
send_buf[0] = received + 5;
Serial.printf("Received: 0x%02X -> Respond: 0x%02X\n", received, send_buf[0]);
}
}
// ---------------------------------------------------------------------
Raspberry Pi のプログラム
master.c
// ------------------------------------------------------------
// master.c
//
// ------------------------------------------------------------
#include <bcm2835.h>
#include <stdio.h>
// ------------------------------------------------------------
void send_read_proc(uint8_t send_data)
{
uint8_t read_data = bcm2835_spi_transfer(send_data);
printf("Sent to SPI: 0x%02X. Read back from SPI: 0x%02X.\n", send_data, read_data);
}
// ------------------------------------------------------------
int main(int argc, char **argv)
{
if (!bcm2835_init())
return 1;
bcm2835_spi_begin();
bcm2835_spi_setBitOrder(BCM2835_SPI_BIT_ORDER_MSBFIRST); // The default
bcm2835_spi_setDataMode(BCM2835_SPI_MODE0); // The default
bcm2835_spi_setClockDivider(BCM2835_SPI_CLOCK_DIVIDER_65536); // The default
bcm2835_spi_chipSelect(BCM2835_SPI_CS0); // The default
bcm2835_spi_setChipSelectPolarity(BCM2835_SPI_CS0, LOW); // the default
uint8_t send_data[] = {0x30,0x31,0x32,0x33,0x34,0x35,0x36};
send_read_proc(send_data[0]);
bcm2835_spi_end();
bcm2835_close();
return 0;
}
// ------------------------------------------------------------
Makefile
master: master.c
gcc -o master master.c -l bcm2835
clean:
rm -f master
実行結果
Raspberry Pi
$ sudo ./master
Sent to SPI: 0x30. Read back from SPI: 0x35.