SPI Pins

See the S# series datasheet for the ESP device you are using > Peripheral Pin Configurations

Resources

https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/spi_master.html

SPI Ports on the ESP32

ESP32 C3

ESP32 C3 integrates 3 SPI peripherals.

SPI0 and SPI1

Used internally to access the ESP32’s attached flash memory.

SPI2

General purpose SPI controller.

ESP32 S3

ESP32 S3 integrates 4 SPI peripherals.

SPI0 and SPI1

Used internally to access the ESP32’s attached flash memory.

SPI2 and SPI3 / HSPI and VSPI

General purpose SPI controllers, sometimes referred to as HSPI and VSPI, respectively. They are open to users.
SPI2 and SPI3 have independent bus signals.
Each bus has three CS lines to drive up to same number of SPI slaves.

SPI Mode

Mode  CPOL  CPHA
0     0     0     Clock idle low, data is clocked in on rising edge, output data (change) on falling edge
1     0     1     Clock idle low, data is clocked in on falling edge, output data (change) on rising edge
2     1     0     Clock idle high, data is clocked in on falling edge, output data (change) on rising edge
3     1     1     Clock idle high, data is clocked in on rising edge, output data (change) on falling edge

Using SPI bus example

#include "driver/spi_master.h"

#define EXAMPLE_SPI_PORT_NAME					SPI2_HOST
#define EXAMPLE_SPI_PIN_MISO					13
#define EXAMPLE_SPI_PIN_MOSI					11
#define EXAMPLE_SPI_PIN_CLK						12
#define EXAMPLE_SPI_PIN_CS						10

#define EXAMPLE_SPI_MAX_TRANSFER_SIZE_BYTES		32			//<<<<<<<<<<<<<<SET THIS BIG ENOUGH!!!

    
	//----- INITIALIZE SPI BUS -----
	spi_device_handle_t  OurSpiDeviceHandle1;

	spi_bus_config_t SpiBusConfig={
		.miso_io_num = EXAMPLE_SPI_PIN_MISO,
		.mosi_io_num = EXAMPLE_SPI_PIN_MOSI,
		.sclk_io_num = EXAMPLE_SPI_PIN_CLK,
		.quadwp_io_num = -1,
		.quadhd_io_num = -1,
		.max_transfer_sz = EXAMPLE_SPI_MAX_TRANSFER_SIZE_BYTES,
		//.intr_flags = ESP_INTR_FLAG_LOWMED,				//<<<Optional, include to ensure SPI doesn't consume a level 1 irq if you are short of irqs
	};
	spi_bus_initialize(EXAMPLE_SPI_PORT_NAME, &SpiBusConfig, SPI_DMA_CH_AUTO);		//<<<You can use ESP_ERROR_CHECK() on this call if you are having issues


	//----- ADD A SPI DEVICE -----
	spi_device_interface_config_t SpiDeviceInterfaceConfig1 = {
		.clock_speed_hz = 10*1000*1000,				//Clock out at 10 MHz
		.mode = 0,									//<<< SPI mode 0
		.spics_io_num = EXAMPLE_SPI_PIN_CS,			//<<< CS pin number
		.queue_size = 1,							//<<< Number of transactions we want to be able to queue at a time using spi_device_queue_trans()
	};
	spi_bus_add_device(EXAMPLE_SPI_PORT_NAME, &SpiDeviceInterfaceConfig1, &OurSpiDeviceHandle1);		//<<<You can use ESP_ERROR_CHECK() on this call if you are having issues


	//-------------------------
	//----- TRANSMIT ONLY -----
	//-------------------------
	uint8_t TxData[2] = {0x01, 0x02};

	spi_transaction_t SpiTransaction;
	memset(&SpiTransaction, 0, sizeof(SpiTransaction));			//Zero out the transaction ready to use
	SpiTransaction.length = 2 * 8;								//Transaction length is in bits
	SpiTransaction.tx_buffer = &TxData;							//Set the tx data buffer
	//Do it
	spi_device_polling_transmit(OurSpiDeviceHandle1, &SpiTransaction);		//Waits until the transfer is complete


	//---------------------------------
	//----- TRANSMIT THEN RECEIVE -----
	//---------------------------------
	//When using SPI_TRANS_CS_KEEP_ACTIVE, bus must be locked/acquired
	spi_device_acquire_bus(OurSpiDeviceHandle1, portMAX_DELAY);

	//----- TRANSMIT BYTES -----
	uint8_t TxData = 0x04;
	spi_transaction_t SpiTransaction;
	memset(&SpiTransaction, 0, sizeof(SpiTransaction));			//Zero out the transaction ready to use
	SpiTransaction.length = 1 * 8;								//Transaction length is in bits
	SpiTransaction.tx_buffer = &TxData;							//Set the tx data buffer
	SpiTransaction.flags = SPI_TRANS_CS_KEEP_ACTIVE;			//Keep CS active after data transfer
	//Do it
	spi_device_polling_transmit(OurSpiDeviceHandle1, &SpiTransaction);		//Waits until the transfer is complete


	//----- RECEIVE BYTES -----
	uint8_t RxData = 0x04;
	memset(&SpiTransaction, 0, sizeof(SpiTransaction));			//Zero out the transaction ready to use
	SpiTransaction.length = 3 * 8;								//Transaction length is in bits
	SpiTransaction.rx_buffer = &RxData[0];
	//Do it
	spi_device_polling_transmit(OurSpiDeviceHandle1, &SpiTransaction);		//Waits until the transfer is complete

	//Release bus
	spi_device_release_bus(OurSpiDeviceHandle1);
USEFUL?
We benefit hugely from resources on the web so we decided we should try and give back some of our knowledge and resources to the community by opening up many of our company’s internal notes and libraries through mini sites like this. We hope you find the site helpful.
Please feel free to comment if you can add help to this page or point out issues and solutions you have found, but please note that we do not provide support on this site. If you need help with a problem please use one of the many online forums.

Comments

  1. Javier

    2 months ago

    excellent!! works for me!!

Comments

Your email address will not be published. Required fields are marked *