mirror of
https://github.com/espressif/ESP8266_RTOS_SDK.git
synced 2025-05-22 01:27:11 +08:00
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:
@ -338,7 +338,7 @@ esp_err_t gpio_config(const gpio_config_t *gpio_cfg)
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void gpio_intr_service(void *arg)
|
||||
void IRAM_ATTR gpio_intr_service(void *arg)
|
||||
{
|
||||
//GPIO intr process
|
||||
uint32_t gpio_num = 0;
|
||||
@ -352,11 +352,10 @@ void gpio_intr_service(void *arg)
|
||||
do {
|
||||
if (gpio_num < GPIO_PIN_COUNT - 1) {
|
||||
if (gpio_intr_status & BIT(gpio_num)) { //gpio0-gpio15
|
||||
GPIO.status_w1tc = BIT(gpio_num);
|
||||
if (gpio_isr_func[gpio_num].fn != NULL) {
|
||||
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);
|
||||
|
@ -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]->slave.slave_mode = 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]->slave.wr_rd_sta_en = 1;
|
||||
SPI[host]->slave1.status_bitlen = 31;
|
||||
|
@ -51,68 +51,24 @@ See the Getting Started Guide for full steps to configure and use ESP-IDF to bui
|
||||
* LOG:
|
||||
|
||||
```
|
||||
I (214) spi_master_example: init gpio
|
||||
I (216) gpio: GPIO[4]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:1
|
||||
I (238) spi_master_example: init spi
|
||||
I (1238) spi_master_example: ------Master read------
|
||||
|
||||
I (1231) spi_master_example: addr: 0x0
|
||||
|
||||
I (1233) spi_master_example: read_data[0]: 0xaaaaaaaa
|
||||
|
||||
I (1249) spi_master_example: read_data[1]: 0xbbbbbbbb
|
||||
|
||||
I (1248) spi_master_example: read_data[2]: 0xcccccccc
|
||||
|
||||
I (1257) spi_master_example: read_data[3]: 0xdddddddd
|
||||
|
||||
I (1266) spi_master_example: read_data[4]: 0xeeeeeeee
|
||||
|
||||
I (1275) spi_master_example: read_data[5]: 0xffffffff
|
||||
|
||||
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
|
||||
I (516) spi_master_example: init gpio
|
||||
I (526) gpio: GPIO[4]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:1
|
||||
I (536) spi_master_example: init spi
|
||||
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 (766) spi_master_example: Master wrote 3200 bytes in 4522 us
|
||||
I (866) spi_master_example: Master wrote 3200 bytes in 4520 us
|
||||
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 (1166) spi_master_example: Master wrote 3200 bytes in 4522 us
|
||||
I (1266) spi_master_example: Master wrote 3200 bytes in 4521 us
|
||||
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 (1566) spi_master_example: Master wrote 3200 bytes in 4520 us
|
||||
I (1666) spi_master_example: Master wrote 3200 bytes in 4519 us
|
||||
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 (1966) spi_master_example: Master wrote 3200 bytes in 4520 us
|
||||
```
|
||||
|
||||
* WAVE FORM:
|
||||
|
@ -8,12 +8,15 @@
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <sys/time.h>
|
||||
#include "freertos/FreeRTOS.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 "esp_system.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
#include "driver/gpio.h"
|
||||
@ -21,61 +24,62 @@
|
||||
|
||||
static const char *TAG = "spi_master_example";
|
||||
|
||||
#define SPI_SLAVE_HANDSHARK_GPIO 4
|
||||
#define SPI_SLAVE_HANDSHARK_SEL (1ULL<<SPI_SLAVE_HANDSHARK_GPIO)
|
||||
#define SPI_MASTER_HANDSHARK_GPIO 4
|
||||
#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)
|
||||
{
|
||||
int x;
|
||||
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) {
|
||||
taskYIELD();
|
||||
if (xHigherPriorityTaskWoken == pdTRUE) {
|
||||
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)
|
||||
{
|
||||
uint16_t cmd;
|
||||
uint32_t addr;
|
||||
int x;
|
||||
uint32_t write_data[8];
|
||||
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.addr = &addr;
|
||||
addr = 0x0;
|
||||
write_data[0] = 0;
|
||||
trans.mosi = write_data;
|
||||
cmd = SPI_MASTER_WRITE_DATA_TO_SLAVE_CMD;
|
||||
addr = 0;
|
||||
write_data[0] = 1;
|
||||
write_data[1] = 0x11111111;
|
||||
write_data[2] = 0x22222222;
|
||||
write_data[3] = 0x33333333;
|
||||
@ -85,103 +89,55 @@ static void spi_master_write_slave_task(void *arg)
|
||||
write_data[7] = 0x77777777;
|
||||
|
||||
while (1) {
|
||||
if (addr % 50 == 0) {
|
||||
vTaskDelay(1000 / portTICK_RATE_MS);
|
||||
}
|
||||
|
||||
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) {
|
||||
gettimeofday(&now, NULL);
|
||||
time_start = now.tv_usec;
|
||||
for (x = 0;x < 100;x++) {
|
||||
spi_trans(HSPI_HOST, trans);
|
||||
if (status == true) {
|
||||
break;
|
||||
}
|
||||
vTaskDelay(10 / portTICK_RATE_MS);
|
||||
write_data[0]++;
|
||||
}
|
||||
gettimeofday(&now, NULL);
|
||||
time_end = now.tv_usec;
|
||||
|
||||
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]++;
|
||||
vTaskDelay(10 / portTICK_RATE_MS);
|
||||
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)
|
||||
{
|
||||
int x;
|
||||
uint32_t io_num;
|
||||
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;
|
||||
uint32_t *read_data = NULL;
|
||||
uint32_t size;
|
||||
|
||||
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) {
|
||||
break;
|
||||
if (read_data) {
|
||||
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)
|
||||
{
|
||||
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");
|
||||
gpio_config_t io_conf;
|
||||
io_conf.intr_type = GPIO_INTR_POSEDGE;
|
||||
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_up_en = 0;
|
||||
gpio_config(&io_conf);
|
||||
|
||||
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");
|
||||
spi_config_t spi_config;
|
||||
@ -197,9 +153,18 @@ void app_main(void)
|
||||
// Set the SPI clock frequency division factor
|
||||
spi_config.clk_div = SPI_10MHz_DIV;
|
||||
// Register SPI event callback function
|
||||
spi_config.event_cb = spi_event_callback;
|
||||
spi_config.event_cb = NULL;
|
||||
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
|
||||
xTaskCreate(spi_master_write_slave_task, "spi_master_write_slave_task", 2048, NULL, 10, NULL);
|
||||
|
||||
|
@ -51,68 +51,24 @@ See the Getting Started Guide for full steps to configure and use ESP-IDF to bui
|
||||
* LOG:
|
||||
|
||||
```
|
||||
I (221) spi_slave_example: init gpio
|
||||
I (223) gpio: GPIO[4]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0
|
||||
I (234) spi_slave_example: init spi
|
||||
I (2516) spi_slave_example: ------Slave read------
|
||||
I (500) spi_slave_example: init gpio
|
||||
I (500) gpio: GPIO[4]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0
|
||||
I (520) spi_slave_example: init spi
|
||||
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:
|
||||
|
@ -8,13 +8,15 @@
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include <sys/time.h>
|
||||
#include "freertos/FreeRTOS.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 "esp_system.h"
|
||||
#include "esp_log.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_SEL (1ULL<<SPI_SLAVE_HANDSHARK_GPIO)
|
||||
|
||||
static SemaphoreHandle_t spi_wr_sta_done_sem = NULL;
|
||||
static SemaphoreHandle_t spi_rd_buf_done_sem = NULL;
|
||||
static SemaphoreHandle_t spi_wr_buf_done_sem = NULL;
|
||||
RingbufHandle_t spi_slave_tx_ring_buf;
|
||||
RingbufHandle_t spi_slave_rx_ring_buf;
|
||||
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)
|
||||
{
|
||||
int x;
|
||||
BaseType_t xHigherPriorityTaskWoken;
|
||||
uint32_t status;
|
||||
uint32_t trans_done;
|
||||
uint32_t *write_data = NULL;
|
||||
uint32_t read_data[8];
|
||||
uint32_t size;
|
||||
|
||||
switch (event) {
|
||||
case SPI_INIT_EVENT: {
|
||||
status = false;
|
||||
spi_slave_set_status(HSPI_HOST, &status);
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
@ -51,21 +58,31 @@ void IRAM_ATTR spi_event_callback(int event, void *arg)
|
||||
trans_done = *(uint32_t *)arg;
|
||||
|
||||
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) {
|
||||
status = false;
|
||||
spi_slave_set_status(HSPI_HOST, &status);
|
||||
xSemaphoreGiveFromISR(spi_wr_buf_done_sem, &xHigherPriorityTaskWoken);
|
||||
for (x = 0; x < 8; x++) {
|
||||
read_data[x] = SPI1.data_buf[x];
|
||||
}
|
||||
xRingbufferSendFromISR(spi_slave_rx_ring_buf, (void *) read_data, sizeof(uint32_t) * 8, &xHigherPriorityTaskWoken);
|
||||
}
|
||||
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) {
|
||||
spi_slave_get_status(HSPI_HOST, &status);
|
||||
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)
|
||||
{
|
||||
int x;
|
||||
uint16_t cmd;
|
||||
uint32_t addr;
|
||||
uint32_t write_data[8];
|
||||
spi_trans_t trans;
|
||||
uint32_t size;
|
||||
uint64_t time_start, time_end;
|
||||
|
||||
trans.cmd = &cmd;
|
||||
trans.addr = &addr;
|
||||
trans.miso = write_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;
|
||||
@ -108,60 +127,45 @@ static void spi_slave_write_master_task(void *arg)
|
||||
write_data[4] = 0xEEEEEEEE;
|
||||
write_data[5] = 0xFFFFFFFF;
|
||||
write_data[6] = 0xAAAABBBB;
|
||||
write_data[7] = 0;
|
||||
write_data[7] = 1;
|
||||
|
||||
// Waiting for master idle
|
||||
xSemaphoreTake(spi_wr_sta_done_sem, portMAX_DELAY);
|
||||
xSemaphoreTake(spi_slave_wr_sta_done_sem, portMAX_DELAY);
|
||||
|
||||
while (1) {
|
||||
gpio_set_level(SPI_SLAVE_HANDSHARK_GPIO, 0);
|
||||
|
||||
if (write_data[7] % 50 == 0) {
|
||||
vTaskDelay(1000 / portTICK_RATE_MS);
|
||||
for (x = 0;x < 100;x++) {
|
||||
xRingbufferSend(spi_slave_tx_ring_buf, (void *) write_data, sizeof(uint32_t) * 8, portMAX_DELAY);
|
||||
write_data[7]++;
|
||||
}
|
||||
|
||||
// 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);
|
||||
write_data[7]++;
|
||||
// The rising edge informs the master to get the data
|
||||
gpio_set_level(SPI_SLAVE_HANDSHARK_GPIO, 1);
|
||||
xSemaphoreTake(spi_rd_buf_done_sem, portMAX_DELAY);
|
||||
vTaskDelay(10 / portTICK_RATE_MS);
|
||||
vRingbufferReturnItem(spi_slave_tx_ring_buf, trans.miso);
|
||||
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)
|
||||
{
|
||||
int x;
|
||||
uint16_t cmd;
|
||||
uint32_t addr;
|
||||
uint32_t read_data[8];
|
||||
spi_trans_t trans;
|
||||
uint32_t status = true;
|
||||
uint32_t *read_data = NULL;
|
||||
uint32_t size;
|
||||
|
||||
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) {
|
||||
spi_slave_set_status(HSPI_HOST, &status);
|
||||
xSemaphoreTake(spi_wr_buf_done_sem, portMAX_DELAY);
|
||||
read_data = (uint32_t *) xRingbufferReceive(spi_slave_rx_ring_buf, &size, portMAX_DELAY);
|
||||
|
||||
spi_trans(HSPI_HOST, trans);
|
||||
|
||||
if (cmd == SPI_MASTER_WRITE_DATA_TO_SLAVE_CMD) {
|
||||
ESP_LOGI(TAG, "------Slave 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]);
|
||||
if (read_data) {
|
||||
vRingbufferReturnItem(spi_slave_rx_ring_buf, read_data);
|
||||
if (read_data[7] % 100 == 0) {
|
||||
vTaskDelay(100 / portTICK_RATE_MS);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -169,9 +173,11 @@ static void spi_slave_read_master_task(void *arg)
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
spi_wr_sta_done_sem = xSemaphoreCreateBinary();
|
||||
spi_rd_buf_done_sem = xSemaphoreCreateBinary();
|
||||
spi_wr_buf_done_sem = xSemaphoreCreateBinary();
|
||||
spi_trans_t trans = {0};
|
||||
spi_slave_tx_ring_buf = xRingbufferCreate(4096, RINGBUF_TYPE_NOSPLIT);
|
||||
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");
|
||||
gpio_config_t io_conf;
|
||||
@ -181,7 +187,7 @@ void app_main(void)
|
||||
io_conf.pull_down_en = 0;
|
||||
io_conf.pull_up_en = 0;
|
||||
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");
|
||||
|
||||
@ -194,12 +200,18 @@ void app_main(void)
|
||||
spi_config.intr_enable.val = SPI_SLAVE_DEFAULT_INTR_ENABLE;
|
||||
// Set SPI to 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
|
||||
spi_config.event_cb = spi_event_callback;
|
||||
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
|
||||
xTaskCreate(spi_slave_write_master_task, "spi_slave_write_master_task", 2048, NULL, 10, NULL);
|
||||
|
||||
|
Reference in New Issue
Block a user