Merge branch 'feature/optimizing_hspi_example' into 'master'

feature(spi): optimizing hspi example

See merge request sdk/ESP8266_RTOS_SDK!841
This commit is contained in:
Wu Jian Gang
2019-04-18 14:16:59 +08:00
6 changed files with 187 additions and 298 deletions

View File

@ -338,7 +338,7 @@ esp_err_t gpio_config(const gpio_config_t *gpio_cfg)
return ESP_OK; return ESP_OK;
} }
void gpio_intr_service(void *arg) void IRAM_ATTR gpio_intr_service(void *arg)
{ {
//GPIO intr process //GPIO intr process
uint32_t gpio_num = 0; uint32_t gpio_num = 0;
@ -352,11 +352,10 @@ void gpio_intr_service(void *arg)
do { do {
if (gpio_num < GPIO_PIN_COUNT - 1) { if (gpio_num < GPIO_PIN_COUNT - 1) {
if (gpio_intr_status & BIT(gpio_num)) { //gpio0-gpio15 if (gpio_intr_status & BIT(gpio_num)) { //gpio0-gpio15
GPIO.status_w1tc = BIT(gpio_num);
if (gpio_isr_func[gpio_num].fn != NULL) { if (gpio_isr_func[gpio_num].fn != NULL) {
gpio_isr_func[gpio_num].fn(gpio_isr_func[gpio_num].args); gpio_isr_func[gpio_num].fn(gpio_isr_func[gpio_num].args);
} }
GPIO.status_w1tc = BIT(gpio_num);
} }
} }
} while (++gpio_num < GPIO_PIN_COUNT - 1); } while (++gpio_num < GPIO_PIN_COUNT - 1);

View File

@ -210,7 +210,8 @@ esp_err_t spi_set_mode(spi_host_t host, spi_mode_t *mode)
SPI[host]->pin.slave_mode = true; SPI[host]->pin.slave_mode = true;
SPI[host]->slave.slave_mode = true; SPI[host]->slave.slave_mode = true;
SPI[host]->user.usr_miso_highpart = true; SPI[host]->user.usr_miso_highpart = true;
SPI[host]->ctrl2.mosi_delay_num = 1; // MOSI signals are delayed by APB_CLK(80MHz) mosi_delay_num cycles
SPI[host]->ctrl2.mosi_delay_num = 2;
SPI[host]->ctrl2.miso_delay_num = 0; SPI[host]->ctrl2.miso_delay_num = 0;
SPI[host]->slave.wr_rd_sta_en = 1; SPI[host]->slave.wr_rd_sta_en = 1;
SPI[host]->slave1.status_bitlen = 31; SPI[host]->slave1.status_bitlen = 31;

View File

@ -51,68 +51,24 @@ See the Getting Started Guide for full steps to configure and use ESP-IDF to bui
* LOG: * LOG:
``` ```
I (214) spi_master_example: init gpio I (516) spi_master_example: init gpio
I (216) gpio: GPIO[4]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:1 I (526) gpio: GPIO[4]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:1
I (238) spi_master_example: init spi I (536) spi_master_example: init spi
I (1238) spi_master_example: ------Master read------ I (556) spi_master_example: Master wrote 3200 bytes in 4302 us
I (656) spi_master_example: Master wrote 3200 bytes in 4519 us
I (1231) spi_master_example: addr: 0x0 I (766) spi_master_example: Master wrote 3200 bytes in 4522 us
I (866) spi_master_example: Master wrote 3200 bytes in 4520 us
I (1233) spi_master_example: read_data[0]: 0xaaaaaaaa I (966) spi_master_example: Master wrote 3200 bytes in 4521 us
I (1066) spi_master_example: Master wrote 3200 bytes in 4520 us
I (1249) spi_master_example: read_data[1]: 0xbbbbbbbb I (1166) spi_master_example: Master wrote 3200 bytes in 4522 us
I (1266) spi_master_example: Master wrote 3200 bytes in 4521 us
I (1248) spi_master_example: read_data[2]: 0xcccccccc I (1366) spi_master_example: Master wrote 3200 bytes in 4520 us
I (1466) spi_master_example: Master wrote 3200 bytes in 4520 us
I (1257) spi_master_example: read_data[3]: 0xdddddddd I (1566) spi_master_example: Master wrote 3200 bytes in 4520 us
I (1666) spi_master_example: Master wrote 3200 bytes in 4519 us
I (1266) spi_master_example: read_data[4]: 0xeeeeeeee I (1766) spi_master_example: Master wrote 3200 bytes in 4521 us
I (1866) spi_master_example: Master wrote 3200 bytes in 4519 us
I (1275) spi_master_example: read_data[5]: 0xffffffff I (1966) spi_master_example: Master wrote 3200 bytes in 4520 us
I (1284) spi_master_example: read_data[6]: 0xaaaabbbb
I (1293) spi_master_example: read_data[7]: 0x0
I (1301) spi_master_example: ------Master read------
I (1310) spi_master_example: addr: 0x1
I (1317) spi_master_example: read_data[0]: 0xaaaaaaaa
I (1326) spi_master_example: read_data[1]: 0xbbbbbbbb
I (1335) spi_master_example: read_data[2]: 0xcccccccc
I (1344) spi_master_example: read_data[3]: 0xdddddddd
I (1353) spi_master_example: read_data[4]: 0xeeeeeeee
I (1363) spi_master_example: read_data[5]: 0xffffffff
I (1372) spi_master_example: read_data[6]: 0xaaaabbbb
I (1381) spi_master_example: read_data[7]: 0x1
I (1399) spi_master_example: ------Master read------
I (1408) spi_master_example: addr: 0x2
I (1405) spi_master_example: read_data[0]: 0xaaaaaaaa
I (1414) spi_master_example: read_data[1]: 0xbbbbbbbb
I (1423) spi_master_example: read_data[2]: 0xcccccccc
I (1432) spi_master_example: read_data[3]: 0xdddddddd
I (1441) spi_master_example: read_data[4]: 0xeeeeeeee
I (1450) spi_master_example: read_data[5]: 0xffffffff
I (1469) spi_master_example: read_data[6]: 0xaaaabbbb
I (1478) spi_master_example: read_data[7]: 0x2
``` ```
* WAVE FORM: * WAVE FORM:

View File

@ -8,12 +8,15 @@
*/ */
#include <stdio.h> #include <stdio.h>
#include <sys/time.h>
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/task.h" #include "freertos/task.h"
#include "freertos/queue.h" #include "freertos/semphr.h"
#include "ringbuf.h"
#include "esp8266/spi_struct.h"
#include "esp8266/gpio_struct.h" #include "esp8266/gpio_struct.h"
#include "esp_system.h"
#include "esp_log.h" #include "esp_log.h"
#include "driver/gpio.h" #include "driver/gpio.h"
@ -21,61 +24,62 @@
static const char *TAG = "spi_master_example"; static const char *TAG = "spi_master_example";
#define SPI_SLAVE_HANDSHARK_GPIO 4 #define SPI_MASTER_HANDSHARK_GPIO 4
#define SPI_SLAVE_HANDSHARK_SEL (1ULL<<SPI_SLAVE_HANDSHARK_GPIO) #define SPI_MASTER_HANDSHARK_SEL (1ULL<<SPI_MASTER_HANDSHARK_GPIO)
static xQueueHandle gpio_evt_queue = NULL; RingbufHandle_t spi_master_rx_ring_buf;
struct timeval now;
static void gpio_isr_handler(void *arg) static void gpio_isr_handler(void *arg)
{ {
int x;
BaseType_t xHigherPriorityTaskWoken; BaseType_t xHigherPriorityTaskWoken;
uint32_t gpio_num = (uint32_t) arg; uint32_t read_data[8];
xQueueSendFromISR(gpio_evt_queue, &gpio_num, &xHigherPriorityTaskWoken); if ((int)arg == SPI_MASTER_HANDSHARK_GPIO) {
while (SPI1.cmd.usr);
SPI1.user.usr_command = 1;
SPI1.user.usr_addr = 1;
SPI1.user.usr_mosi = 0;
SPI1.user.usr_miso = 1;
SPI1.user2.usr_command_bitlen = 8 - 1;
SPI1.user1.usr_addr_bitlen = 32 - 1;
SPI1.user1.usr_miso_bitlen = 32 * 8 - 1;
SPI1.user2.usr_command_value = SPI_MASTER_READ_DATA_FROM_SLAVE_CMD;
SPI1.addr = 0;
SPI1.cmd.usr = 1;
while (SPI1.cmd.usr);
for (x = 0; x < 8; x++) {
read_data[x] = SPI1.data_buf[x];
}
xRingbufferSendFromISR(spi_master_rx_ring_buf, (void *) read_data, sizeof(uint32_t) * 8, &xHigherPriorityTaskWoken);
if (xHigherPriorityTaskWoken == pdTRUE) { if (xHigherPriorityTaskWoken == pdTRUE) {
taskYIELD(); taskYIELD();
} }
}
void IRAM_ATTR spi_event_callback(int event, void *arg)
{
switch (event) {
case SPI_INIT_EVENT: {
} }
break;
case SPI_TRANS_START_EVENT: {
}
break;
case SPI_TRANS_DONE_EVENT: {
}
break;
case SPI_DEINIT_EVENT: {
}
break;
}
} }
static void spi_master_write_slave_task(void *arg) static void spi_master_write_slave_task(void *arg)
{ {
uint16_t cmd; int x;
uint32_t addr;
uint32_t write_data[8]; uint32_t write_data[8];
spi_trans_t trans; spi_trans_t trans;
uint32_t status; uint16_t cmd;
uint32_t addr;
uint64_t time_start, time_end;
trans.bits.val = 0;
trans.bits.cmd = 8 * 1;
trans.bits.addr = 32 * 1;
trans.bits.mosi = 32 * 8;
// Write data to the ESP8266 Slave use "SPI_MASTER_WRITE_DATA_TO_SLAVE_CMD" cmd
trans.cmd = &cmd; trans.cmd = &cmd;
trans.addr = &addr; trans.addr = &addr;
addr = 0x0; trans.mosi = write_data;
write_data[0] = 0; cmd = SPI_MASTER_WRITE_DATA_TO_SLAVE_CMD;
addr = 0;
write_data[0] = 1;
write_data[1] = 0x11111111; write_data[1] = 0x11111111;
write_data[2] = 0x22222222; write_data[2] = 0x22222222;
write_data[3] = 0x33333333; write_data[3] = 0x33333333;
@ -85,103 +89,55 @@ static void spi_master_write_slave_task(void *arg)
write_data[7] = 0x77777777; write_data[7] = 0x77777777;
while (1) { while (1) {
if (addr % 50 == 0) { gettimeofday(&now, NULL);
vTaskDelay(1000 / portTICK_RATE_MS); time_start = now.tv_usec;
} for (x = 0;x < 100;x++) {
trans.miso = &status;
trans.bits.val = 0;
trans.bits.cmd = 8 * 1;
trans.bits.miso = 32 * 1;
// Read status from the ESP8266 Slave use "SPI_MASTER_READ_STATUS_FROM_SLAVE_CMD" cmd
cmd = SPI_MASTER_READ_STATUS_FROM_SLAVE_CMD;
// Get the slave status and send data when the slave is idle
while (1) {
spi_trans(HSPI_HOST, trans); spi_trans(HSPI_HOST, trans);
if (status == true) {
break;
}
vTaskDelay(10 / portTICK_RATE_MS);
}
trans.mosi = write_data;
trans.bits.val = 0;
trans.bits.cmd = 8 * 1;
trans.bits.addr = 32 * 1;
trans.bits.mosi = 32 * 8;
// Write data to the ESP8266 Slave use "SPI_MASTER_WRITE_DATA_TO_SLAVE_CMD" cmd
cmd = SPI_MASTER_WRITE_DATA_TO_SLAVE_CMD;
spi_trans(HSPI_HOST, trans);
addr++;
write_data[0]++; write_data[0]++;
vTaskDelay(10 / portTICK_RATE_MS); }
gettimeofday(&now, NULL);
time_end = now.tv_usec;
ESP_LOGI(TAG, "Master wrote 3200 bytes in %d us", (int)(time_end - time_start));
vTaskDelay(100 / portTICK_RATE_MS);
} }
} }
static void spi_master_read_slave_task(void *arg) static void spi_master_read_slave_task(void *arg)
{ {
int x; uint32_t *read_data = NULL;
uint32_t io_num; uint32_t size;
uint16_t cmd;
uint32_t addr;
uint32_t read_data[8];
spi_trans_t trans;
uint32_t status = true;
trans.cmd = &cmd;
// Write status to the ESP8266 Slave use "SPI_MASTER_WRITE_STATUS_TO_SLAVE_CMD" cmd
cmd = SPI_MASTER_WRITE_STATUS_TO_SLAVE_CMD;
trans.mosi = &status;
trans.bits.val = 0;
trans.bits.cmd = 8 * 1;
trans.bits.mosi = 32 * 1;
spi_trans(HSPI_HOST, trans);
trans.addr = &addr;
trans.miso = read_data;
trans.bits.val = 0;
trans.bits.cmd = 8 * 1;
trans.bits.addr = 32 * 1;
trans.bits.miso = 32 * 8;
// Read data from the ESP8266 Slave use "SPI_MASTER_READ_DATA_FROM_SLAVE_CMD" cmd
cmd = SPI_MASTER_READ_DATA_FROM_SLAVE_CMD;
addr = 0x0;
while (1) { while (1) {
xQueueReceive(gpio_evt_queue, &io_num, portMAX_DELAY); read_data = (uint32_t *) xRingbufferReceive(spi_master_rx_ring_buf, &size, portMAX_DELAY);
if (SPI_SLAVE_HANDSHARK_GPIO != io_num) { if (read_data) {
break; vRingbufferReturnItem(spi_master_rx_ring_buf, read_data);
if (read_data[7] % 100 == 0) {
vTaskDelay(100 / portTICK_RATE_MS);
} }
spi_trans(HSPI_HOST, trans);
ESP_LOGI(TAG, "------Master read------\n");
ESP_LOGI(TAG, "addr: 0x%x\n", addr);
for (x = 0; x < 8; x++) {
ESP_LOGI(TAG, "read_data[%d]: 0x%x\n", x, read_data[x]);
} }
addr++;
} }
} }
void app_main(void) void app_main(void)
{ {
gpio_evt_queue = xQueueCreate(1, sizeof(uint32_t)); spi_trans_t trans = {0};
uint16_t cmd;
uint32_t status = true;
spi_master_rx_ring_buf = xRingbufferCreate(4096, RINGBUF_TYPE_NOSPLIT);
ESP_LOGI(TAG, "init gpio"); ESP_LOGI(TAG, "init gpio");
gpio_config_t io_conf; gpio_config_t io_conf;
io_conf.intr_type = GPIO_INTR_POSEDGE; io_conf.intr_type = GPIO_INTR_POSEDGE;
io_conf.mode = GPIO_MODE_INPUT; io_conf.mode = GPIO_MODE_INPUT;
io_conf.pin_bit_mask = SPI_SLAVE_HANDSHARK_SEL; io_conf.pin_bit_mask = SPI_MASTER_HANDSHARK_SEL;
io_conf.pull_down_en = 0; io_conf.pull_down_en = 0;
io_conf.pull_up_en = 0; io_conf.pull_up_en = 0;
gpio_config(&io_conf); gpio_config(&io_conf);
gpio_install_isr_service(0); gpio_install_isr_service(0);
gpio_isr_handler_add(SPI_SLAVE_HANDSHARK_GPIO, gpio_isr_handler, (void *) SPI_SLAVE_HANDSHARK_GPIO); gpio_isr_handler_add(SPI_MASTER_HANDSHARK_GPIO, gpio_isr_handler, (void *) SPI_MASTER_HANDSHARK_GPIO);
ESP_LOGI(TAG, "init spi"); ESP_LOGI(TAG, "init spi");
spi_config_t spi_config; spi_config_t spi_config;
@ -197,9 +153,18 @@ void app_main(void)
// Set the SPI clock frequency division factor // Set the SPI clock frequency division factor
spi_config.clk_div = SPI_10MHz_DIV; spi_config.clk_div = SPI_10MHz_DIV;
// Register SPI event callback function // Register SPI event callback function
spi_config.event_cb = spi_event_callback; spi_config.event_cb = NULL;
spi_init(HSPI_HOST, &spi_config); spi_init(HSPI_HOST, &spi_config);
// Write status to the ESP8266 Slave use "SPI_MASTER_WRITE_STATUS_TO_SLAVE_CMD" cmd
cmd = SPI_MASTER_WRITE_STATUS_TO_SLAVE_CMD;
trans.cmd = &cmd;
trans.mosi = &status;
trans.bits.val = 0;
trans.bits.cmd = 8 * 1;
trans.bits.mosi = 32 * 1;
spi_trans(HSPI_HOST, trans);
// create spi_master_write_slave_task // create spi_master_write_slave_task
xTaskCreate(spi_master_write_slave_task, "spi_master_write_slave_task", 2048, NULL, 10, NULL); xTaskCreate(spi_master_write_slave_task, "spi_master_write_slave_task", 2048, NULL, 10, NULL);

View File

@ -51,68 +51,24 @@ See the Getting Started Guide for full steps to configure and use ESP-IDF to bui
* LOG: * LOG:
``` ```
I (221) spi_slave_example: init gpio I (500) spi_slave_example: init gpio
I (223) gpio: GPIO[4]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 I (500) gpio: GPIO[4]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0
I (234) spi_slave_example: init spi I (520) spi_slave_example: init spi
I (2516) spi_slave_example: ------Slave read------ I (3390) spi_slave_example: Slave wrote 3200 bytes in 4632 us
I (3490) spi_slave_example: Slave wrote 3200 bytes in 4616 us
I (3590) spi_slave_example: Slave wrote 3200 bytes in 4622 us
I (3690) spi_slave_example: Slave wrote 3200 bytes in 4611 us
I (3790) spi_slave_example: Slave wrote 3200 bytes in 4612 us
I (3890) spi_slave_example: Slave wrote 3200 bytes in 4612 us
I (3990) spi_slave_example: Slave wrote 3200 bytes in 4619 us
I (4090) spi_slave_example: Slave wrote 3200 bytes in 4607 us
I (4190) spi_slave_example: Slave wrote 3200 bytes in 4613 us
I (4290) spi_slave_example: Slave wrote 3200 bytes in 4609 us
I (4390) spi_slave_example: Slave wrote 3200 bytes in 4618 us
I (4490) spi_slave_example: Slave wrote 3200 bytes in 4619 us
I (4590) spi_slave_example: Slave wrote 3200 bytes in 4614 us
I (4690) spi_slave_example: Slave wrote 3200 bytes in 4613 us
I (2519) spi_slave_example: addr: 0x0
I (2511) spi_slave_example: read_data[0]: 0x0
I (2515) spi_slave_example: read_data[1]: 0x11111111
I (2524) spi_slave_example: read_data[2]: 0x22222222
I (2533) spi_slave_example: read_data[3]: 0x33333333
I (2542) spi_slave_example: read_data[4]: 0x44444444
I (2551) spi_slave_example: read_data[5]: 0x55555555
I (2560) spi_slave_example: read_data[6]: 0x66666666
I (2579) spi_slave_example: read_data[7]: 0x77777777
I (2596) spi_slave_example: ------Slave read------
I (2599) spi_slave_example: addr: 0x1
I (2593) spi_slave_example: read_data[0]: 0x1
I (2601) spi_slave_example: read_data[1]: 0x11111111
I (2610) spi_slave_example: read_data[2]: 0x22222222
I (2629) spi_slave_example: read_data[3]: 0x33333333
I (2638) spi_slave_example: read_data[4]: 0x44444444
I (2647) spi_slave_example: read_data[5]: 0x55555555
I (2656) spi_slave_example: read_data[6]: 0x66666666
I (2655) spi_slave_example: read_data[7]: 0x77777777
I (2676) spi_slave_example: ------Slave read------
I (2672) spi_slave_example: addr: 0x2
I (2689) spi_slave_example: read_data[0]: 0x2
I (2697) spi_slave_example: read_data[1]: 0x11111111
I (2706) spi_slave_example: read_data[2]: 0x22222222
I (2705) spi_slave_example: read_data[3]: 0x33333333
I (2714) spi_slave_example: read_data[4]: 0x44444444
I (2723) spi_slave_example: read_data[5]: 0x55555555
I (2732) spi_slave_example: read_data[6]: 0x66666666
I (2741) spi_slave_example: read_data[7]: 0x77777777
``` ```
* WAVE FORM: * WAVE FORM:

View File

@ -8,13 +8,15 @@
*/ */
#include <stdio.h> #include <stdio.h>
#include <sys/time.h>
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/task.h" #include "freertos/task.h"
#include "freertos/queue.h"
#include "freertos/semphr.h" #include "freertos/semphr.h"
#include "ringbuf.h"
#include "esp8266/spi_struct.h"
#include "esp8266/gpio_struct.h" #include "esp8266/gpio_struct.h"
#include "esp_system.h"
#include "esp_log.h" #include "esp_log.h"
#include "driver/gpio.h" #include "driver/gpio.h"
@ -25,20 +27,25 @@ static const char *TAG = "spi_slave_example";
#define SPI_SLAVE_HANDSHARK_GPIO 4 #define SPI_SLAVE_HANDSHARK_GPIO 4
#define SPI_SLAVE_HANDSHARK_SEL (1ULL<<SPI_SLAVE_HANDSHARK_GPIO) #define SPI_SLAVE_HANDSHARK_SEL (1ULL<<SPI_SLAVE_HANDSHARK_GPIO)
static SemaphoreHandle_t spi_wr_sta_done_sem = NULL; RingbufHandle_t spi_slave_tx_ring_buf;
static SemaphoreHandle_t spi_rd_buf_done_sem = NULL; RingbufHandle_t spi_slave_rx_ring_buf;
static SemaphoreHandle_t spi_wr_buf_done_sem = NULL; static SemaphoreHandle_t spi_slave_tx_done_sem = NULL;
static SemaphoreHandle_t spi_slave_wr_sta_done_sem = NULL;
static struct timeval now;
void IRAM_ATTR spi_event_callback(int event, void *arg) void IRAM_ATTR spi_event_callback(int event, void *arg)
{ {
int x;
BaseType_t xHigherPriorityTaskWoken; BaseType_t xHigherPriorityTaskWoken;
uint32_t status; uint32_t status;
uint32_t trans_done; uint32_t trans_done;
uint32_t *write_data = NULL;
uint32_t read_data[8];
uint32_t size;
switch (event) { switch (event) {
case SPI_INIT_EVENT: { case SPI_INIT_EVENT: {
status = false;
spi_slave_set_status(HSPI_HOST, &status);
} }
break; break;
@ -51,21 +58,31 @@ void IRAM_ATTR spi_event_callback(int event, void *arg)
trans_done = *(uint32_t *)arg; trans_done = *(uint32_t *)arg;
if (trans_done & SPI_SLV_RD_BUF_DONE) { if (trans_done & SPI_SLV_RD_BUF_DONE) {
xSemaphoreGiveFromISR(spi_rd_buf_done_sem, &xHigherPriorityTaskWoken); gpio_set_level(SPI_SLAVE_HANDSHARK_GPIO, 0);
write_data = (uint32_t *) xRingbufferReceiveFromISR(spi_slave_tx_ring_buf, &size);
if (write_data) {
for (x = 0; x < 8; x++) {
SPI1.data_buf[x + 8] = write_data[x];
}
vRingbufferReturnItemFromISR(spi_slave_tx_ring_buf, write_data, &xHigherPriorityTaskWoken);
gpio_set_level(SPI_SLAVE_HANDSHARK_GPIO, 1);
} else {
xSemaphoreGiveFromISR(spi_slave_tx_done_sem, &xHigherPriorityTaskWoken);
}
} }
if (trans_done & SPI_SLV_WR_BUF_DONE) { if (trans_done & SPI_SLV_WR_BUF_DONE) {
status = false; for (x = 0; x < 8; x++) {
spi_slave_set_status(HSPI_HOST, &status); read_data[x] = SPI1.data_buf[x];
xSemaphoreGiveFromISR(spi_wr_buf_done_sem, &xHigherPriorityTaskWoken); }
xRingbufferSendFromISR(spi_slave_rx_ring_buf, (void *) read_data, sizeof(uint32_t) * 8, &xHigherPriorityTaskWoken);
} }
if (trans_done & SPI_SLV_RD_STA_DONE) { if (trans_done & SPI_SLV_RD_STA_DONE) {
status = false;
spi_slave_set_status(HSPI_HOST, &status);
} }
if (trans_done & SPI_SLV_WR_STA_DONE) { if (trans_done & SPI_SLV_WR_STA_DONE) {
spi_slave_get_status(HSPI_HOST, &status); spi_slave_get_status(HSPI_HOST, &status);
if (status == true) { if (status == true) {
xSemaphoreGiveFromISR(spi_wr_sta_done_sem, &xHigherPriorityTaskWoken); xSemaphoreGiveFromISR(spi_slave_wr_sta_done_sem, &xHigherPriorityTaskWoken);
} }
} }
@ -85,14 +102,16 @@ void IRAM_ATTR spi_event_callback(int event, void *arg)
static void spi_slave_write_master_task(void *arg) static void spi_slave_write_master_task(void *arg)
{ {
int x;
uint16_t cmd; uint16_t cmd;
uint32_t addr; uint32_t addr;
uint32_t write_data[8]; uint32_t write_data[8];
spi_trans_t trans; spi_trans_t trans;
uint32_t size;
uint64_t time_start, time_end;
trans.cmd = &cmd; trans.cmd = &cmd;
trans.addr = &addr; trans.addr = &addr;
trans.miso = write_data;
trans.bits.val = 0; trans.bits.val = 0;
// In Slave mode, spi cmd must be longer than 3 bits and shorter than 16 bits // In Slave mode, spi cmd must be longer than 3 bits and shorter than 16 bits
trans.bits.cmd = 8 * 1; trans.bits.cmd = 8 * 1;
@ -108,60 +127,45 @@ static void spi_slave_write_master_task(void *arg)
write_data[4] = 0xEEEEEEEE; write_data[4] = 0xEEEEEEEE;
write_data[5] = 0xFFFFFFFF; write_data[5] = 0xFFFFFFFF;
write_data[6] = 0xAAAABBBB; write_data[6] = 0xAAAABBBB;
write_data[7] = 0; write_data[7] = 1;
// Waiting for master idle // Waiting for master idle
xSemaphoreTake(spi_wr_sta_done_sem, portMAX_DELAY); xSemaphoreTake(spi_slave_wr_sta_done_sem, portMAX_DELAY);
while (1) { while (1) {
gpio_set_level(SPI_SLAVE_HANDSHARK_GPIO, 0); for (x = 0;x < 100;x++) {
xRingbufferSend(spi_slave_tx_ring_buf, (void *) write_data, sizeof(uint32_t) * 8, portMAX_DELAY);
if (write_data[7] % 50 == 0) { write_data[7]++;
vTaskDelay(1000 / portTICK_RATE_MS);
} }
// load new data trans.miso = (uint32_t *) xRingbufferReceive(spi_slave_tx_ring_buf, &size, portMAX_DELAY);
gettimeofday(&now, NULL);
time_start = now.tv_usec;
gpio_set_level(SPI_SLAVE_HANDSHARK_GPIO, 0);
spi_trans(HSPI_HOST, trans); spi_trans(HSPI_HOST, trans);
write_data[7]++;
// The rising edge informs the master to get the data
gpio_set_level(SPI_SLAVE_HANDSHARK_GPIO, 1); gpio_set_level(SPI_SLAVE_HANDSHARK_GPIO, 1);
xSemaphoreTake(spi_rd_buf_done_sem, portMAX_DELAY); vRingbufferReturnItem(spi_slave_tx_ring_buf, trans.miso);
vTaskDelay(10 / portTICK_RATE_MS); xSemaphoreTake(spi_slave_tx_done_sem, portMAX_DELAY);
gettimeofday(&now, NULL);
time_end = now.tv_usec;
ESP_LOGI(TAG, "Slave wrote 3200 bytes in %d us", (int)(time_end - time_start));
vTaskDelay(100 / portTICK_RATE_MS);
} }
} }
static void spi_slave_read_master_task(void *arg) static void spi_slave_read_master_task(void *arg)
{ {
int x; uint32_t *read_data = NULL;
uint16_t cmd; uint32_t size;
uint32_t addr;
uint32_t read_data[8];
spi_trans_t trans;
uint32_t status = true;
trans.cmd = &cmd;
trans.addr = &addr;
trans.mosi = read_data;
trans.bits.val = 0;
// In Slave mode, spi cmd must be longer than 3 bits and shorter than 16 bits
trans.bits.cmd = 8 * 1;
// In Slave mode, spi addr must be longer than 1 bits and shorter than 32 bits
trans.bits.addr = 32 * 1;
trans.bits.mosi = 32 * 8;
spi_trans(HSPI_HOST, trans); // init spi slave buf
while (1) { while (1) {
spi_slave_set_status(HSPI_HOST, &status); read_data = (uint32_t *) xRingbufferReceive(spi_slave_rx_ring_buf, &size, portMAX_DELAY);
xSemaphoreTake(spi_wr_buf_done_sem, portMAX_DELAY);
spi_trans(HSPI_HOST, trans); if (read_data) {
vRingbufferReturnItem(spi_slave_rx_ring_buf, read_data);
if (cmd == SPI_MASTER_WRITE_DATA_TO_SLAVE_CMD) { if (read_data[7] % 100 == 0) {
ESP_LOGI(TAG, "------Slave read------\n"); vTaskDelay(100 / portTICK_RATE_MS);
ESP_LOGI(TAG, "addr: 0x%x\n", addr);
for (x = 0; x < 8; x++) {
ESP_LOGI(TAG, "read_data[%d]: 0x%x\n", x, read_data[x]);
} }
} }
} }
@ -169,9 +173,11 @@ static void spi_slave_read_master_task(void *arg)
void app_main(void) void app_main(void)
{ {
spi_wr_sta_done_sem = xSemaphoreCreateBinary(); spi_trans_t trans = {0};
spi_rd_buf_done_sem = xSemaphoreCreateBinary(); spi_slave_tx_ring_buf = xRingbufferCreate(4096, RINGBUF_TYPE_NOSPLIT);
spi_wr_buf_done_sem = xSemaphoreCreateBinary(); spi_slave_rx_ring_buf = xRingbufferCreate(4096, RINGBUF_TYPE_NOSPLIT);
spi_slave_wr_sta_done_sem = xSemaphoreCreateBinary();
spi_slave_tx_done_sem = xSemaphoreCreateBinary();
ESP_LOGI(TAG, "init gpio"); ESP_LOGI(TAG, "init gpio");
gpio_config_t io_conf; gpio_config_t io_conf;
@ -181,7 +187,7 @@ void app_main(void)
io_conf.pull_down_en = 0; io_conf.pull_down_en = 0;
io_conf.pull_up_en = 0; io_conf.pull_up_en = 0;
gpio_config(&io_conf); gpio_config(&io_conf);
gpio_set_level(SPI_SLAVE_HANDSHARK_GPIO, 1); gpio_set_level(SPI_SLAVE_HANDSHARK_GPIO, 0);
ESP_LOGI(TAG, "init spi"); ESP_LOGI(TAG, "init spi");
@ -194,12 +200,18 @@ void app_main(void)
spi_config.intr_enable.val = SPI_SLAVE_DEFAULT_INTR_ENABLE; spi_config.intr_enable.val = SPI_SLAVE_DEFAULT_INTR_ENABLE;
// Set SPI to slave mode // Set SPI to slave mode
spi_config.mode = SPI_SLAVE_MODE; spi_config.mode = SPI_SLAVE_MODE;
// Set the SPI clock frequency division factor
spi_config.clk_div = SPI_10MHz_DIV;
// Register SPI event callback function // Register SPI event callback function
spi_config.event_cb = spi_event_callback; spi_config.event_cb = spi_event_callback;
spi_init(HSPI_HOST, &spi_config); spi_init(HSPI_HOST, &spi_config);
trans.bits.val = 0;
// In Slave mode, spi cmd must be longer than 3 bits and shorter than 16 bits
trans.bits.cmd = 8 * 1;
// In Slave mode, spi addr must be longer than 1 bits and shorter than 32 bits
trans.bits.addr = 32 * 1;
trans.bits.mosi = 32 * 8;
spi_trans(HSPI_HOST, trans); // init spi slave buf
// create spi_slave_write_master_task // create spi_slave_write_master_task
xTaskCreate(spi_slave_write_master_task, "spi_slave_write_master_task", 2048, NULL, 10, NULL); xTaskCreate(spi_slave_write_master_task, "spi_slave_write_master_task", 2048, NULL, 10, NULL);