ESP 32 Spi example cant reach 40 Mhz
Posted: Fri Jan 14, 2022 2:48 pm
Hello im trying to test the SPI speed with a loop between the MISO and MOSI pin.
To get a fast entry point i used the \examples\peripherals\spi_slave\sender project.
I changed the pins to the VSPI iomux pins so can still debug.
My Problem is now i can only go up to 26 mhz instead of up to 80 Mhz like the ref man api ref and datasheet r telling is the max Speed for SPI master.
My hardware is the https://docs.espressif.com/projects/esp ... it-v3.html
1. cant setup 80 Mhz for clock speed than the rxbuffer has the wrong data inside
2. i recognized that the dutycycle is not 50/50 its more 30/70 see logicAnalyzer screenshot in the attachments(ok solved this it was bc logic analyzers Sample rate was to low with an oszi it was good)
Would be very nice if someone can have a look and help me.
[Codebox]
#include <stdio.h>
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "freertos/queue.h"
#include "lwip/sockets.h"
#include "lwip/dns.h"
#include "lwip/netdb.h"
#include "lwip/igmp.h"
#include "esp_wifi.h"
#include "esp_system.h"
#include "esp_event.h"
#include "nvs_flash.h"
#include "soc/rtc_periph.h"
#include "driver/spi_master.h"
#include "esp_log.h"
#include "esp_spi_flash.h"
#include "driver/gpio.h"
#include "esp_intr_alloc.h"
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
//#define GPIO_HANDSHAKE 2
#define GPIO_MOSI 23
#define GPIO_MISO 19
#define GPIO_SCLK 18
#define GPIO_CS 5
#elif CONFIG_IDF_TARGET_ESP32C3
#define GPIO_HANDSHAKE 3
#define GPIO_MOSI 7
#define GPIO_MISO 2
#define GPIO_SCLK 6
#define GPIO_CS 10
#endif //CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
#ifdef CONFIG_IDF_TARGET_ESP32
#define SENDER_HOST 2
#elif defined CONFIG_IDF_TARGET_ESP32S2
#define SENDER_HOST SPI2_HOST
#elif defined CONFIG_IDF_TARGET_ESP32C3
#define SENDER_HOST SPI2_HOST
#endif
//The semaphore indicating the slave is ready to receive stuff.
static xQueueHandle rdySem;
//Main application
void app_main(void)
{
esp_err_t ret;
spi_device_handle_t handle;
//Configuration for the SPI bus
spi_bus_config_t buscfg={
.mosi_io_num=GPIO_MOSI,
.miso_io_num=GPIO_MISO,
.sclk_io_num=GPIO_SCLK,
.quadwp_io_num=22,
.quadhd_io_num=21
};
//Configuration for the SPI device on the other side of the bus
spi_device_interface_config_t devcfg={
.command_bits=0,
.address_bits=0,
.dummy_bits=0,
.clock_speed_hz=SPI_MASTER_FREQ_80M,
.duty_cycle_pos=0, //50% duty cycle
.mode=0,
.spics_io_num=5,
.cs_ena_posttrans=0,
.queue_size=3
};
int n=0;
char sendbuf[128] = {0};
char recvbuf[128] = {0};
spi_transaction_t t;
memset(&t, 0, sizeof(t));
//Create the semaphore.
rdySem=xSemaphoreCreateBinary();
//Initialize the SPI bus and add the device we want to send stuff to.
ret=spi_bus_initialize(SENDER_HOST, &buscfg, SPI_DMA_CH_AUTO);
assert(ret==ESP_OK);
ret=spi_bus_add_device(SENDER_HOST, &devcfg, &handle);
assert(ret==ESP_OK);
//Assume the slave is ready for the first transmission: if the slave started up before us, we will not detect
//positive edge on the handshake line.
xSemaphoreGive(rdySem);
while(1) {
int res = snprintf(sendbuf, sizeof(sendbuf),
"Sender, transmission no. %04i. Last time, I received: \"%s\"", n, recvbuf);
if (res >= sizeof(sendbuf)) {
printf("Data truncated\n");
}
// t.length=sizeof(sendbuf)*8;
t.length=8*strlen(sendbuf);
t.tx_buffer=sendbuf;
t.rx_buffer=recvbuf;
//Wait for slave to be ready for next byte before sending
// xSemaphoreTake(rdySem, portMAX_DELAY); //Wait until slave is ready
ret=spi_device_transmit(handle, &t);
printf("Received: %s\n", recvbuf);
n++;
}
//Never reached.
ret=spi_bus_remove_device(handle);
assert(ret==ESP_OK);
}
[/Codebox]
To get a fast entry point i used the \examples\peripherals\spi_slave\sender project.
I changed the pins to the VSPI iomux pins so can still debug.
My Problem is now i can only go up to 26 mhz instead of up to 80 Mhz like the ref man api ref and datasheet r telling is the max Speed for SPI master.
My hardware is the https://docs.espressif.com/projects/esp ... it-v3.html
1. cant setup 80 Mhz for clock speed than the rxbuffer has the wrong data inside
2. i recognized that the dutycycle is not 50/50 its more 30/70 see logicAnalyzer screenshot in the attachments(ok solved this it was bc logic analyzers Sample rate was to low with an oszi it was good)
Would be very nice if someone can have a look and help me.
[Codebox]
#include <stdio.h>
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/semphr.h"
#include "freertos/queue.h"
#include "lwip/sockets.h"
#include "lwip/dns.h"
#include "lwip/netdb.h"
#include "lwip/igmp.h"
#include "esp_wifi.h"
#include "esp_system.h"
#include "esp_event.h"
#include "nvs_flash.h"
#include "soc/rtc_periph.h"
#include "driver/spi_master.h"
#include "esp_log.h"
#include "esp_spi_flash.h"
#include "driver/gpio.h"
#include "esp_intr_alloc.h"
#if CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
//#define GPIO_HANDSHAKE 2
#define GPIO_MOSI 23
#define GPIO_MISO 19
#define GPIO_SCLK 18
#define GPIO_CS 5
#elif CONFIG_IDF_TARGET_ESP32C3
#define GPIO_HANDSHAKE 3
#define GPIO_MOSI 7
#define GPIO_MISO 2
#define GPIO_SCLK 6
#define GPIO_CS 10
#endif //CONFIG_IDF_TARGET_ESP32 || CONFIG_IDF_TARGET_ESP32S2
#ifdef CONFIG_IDF_TARGET_ESP32
#define SENDER_HOST 2
#elif defined CONFIG_IDF_TARGET_ESP32S2
#define SENDER_HOST SPI2_HOST
#elif defined CONFIG_IDF_TARGET_ESP32C3
#define SENDER_HOST SPI2_HOST
#endif
//The semaphore indicating the slave is ready to receive stuff.
static xQueueHandle rdySem;
//Main application
void app_main(void)
{
esp_err_t ret;
spi_device_handle_t handle;
//Configuration for the SPI bus
spi_bus_config_t buscfg={
.mosi_io_num=GPIO_MOSI,
.miso_io_num=GPIO_MISO,
.sclk_io_num=GPIO_SCLK,
.quadwp_io_num=22,
.quadhd_io_num=21
};
//Configuration for the SPI device on the other side of the bus
spi_device_interface_config_t devcfg={
.command_bits=0,
.address_bits=0,
.dummy_bits=0,
.clock_speed_hz=SPI_MASTER_FREQ_80M,
.duty_cycle_pos=0, //50% duty cycle
.mode=0,
.spics_io_num=5,
.cs_ena_posttrans=0,
.queue_size=3
};
int n=0;
char sendbuf[128] = {0};
char recvbuf[128] = {0};
spi_transaction_t t;
memset(&t, 0, sizeof(t));
//Create the semaphore.
rdySem=xSemaphoreCreateBinary();
//Initialize the SPI bus and add the device we want to send stuff to.
ret=spi_bus_initialize(SENDER_HOST, &buscfg, SPI_DMA_CH_AUTO);
assert(ret==ESP_OK);
ret=spi_bus_add_device(SENDER_HOST, &devcfg, &handle);
assert(ret==ESP_OK);
//Assume the slave is ready for the first transmission: if the slave started up before us, we will not detect
//positive edge on the handshake line.
xSemaphoreGive(rdySem);
while(1) {
int res = snprintf(sendbuf, sizeof(sendbuf),
"Sender, transmission no. %04i. Last time, I received: \"%s\"", n, recvbuf);
if (res >= sizeof(sendbuf)) {
printf("Data truncated\n");
}
// t.length=sizeof(sendbuf)*8;
t.length=8*strlen(sendbuf);
t.tx_buffer=sendbuf;
t.rx_buffer=recvbuf;
//Wait for slave to be ready for next byte before sending
// xSemaphoreTake(rdySem, portMAX_DELAY); //Wait until slave is ready
ret=spi_device_transmit(handle, &t);
printf("Received: %s\n", recvbuf);
n++;
}
//Never reached.
ret=spi_bus_remove_device(handle);
assert(ret==ESP_OK);
}
[/Codebox]