Skip to content

Commit 2f3aa40

Browse files
committed
feature(spi): optimizing hspi example
1 parent f3c97bb commit 2f3aa40

File tree

6 files changed

+185
-296
lines changed

6 files changed

+185
-296
lines changed

components/esp8266/driver/gpio.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ esp_err_t gpio_config(const gpio_config_t *gpio_cfg)
338338
return ESP_OK;
339339
}
340340

341-
void gpio_intr_service(void *arg)
341+
void IRAM_ATTR gpio_intr_service(void *arg)
342342
{
343343
//GPIO intr process
344344
uint32_t gpio_num = 0;
@@ -352,11 +352,10 @@ void gpio_intr_service(void *arg)
352352
do {
353353
if (gpio_num < GPIO_PIN_COUNT - 1) {
354354
if (gpio_intr_status & BIT(gpio_num)) { //gpio0-gpio15
355+
GPIO.status_w1tc = BIT(gpio_num);
355356
if (gpio_isr_func[gpio_num].fn != NULL) {
356357
gpio_isr_func[gpio_num].fn(gpio_isr_func[gpio_num].args);
357358
}
358-
359-
GPIO.status_w1tc = BIT(gpio_num);
360359
}
361360
}
362361
} while (++gpio_num < GPIO_PIN_COUNT - 1);

components/esp8266/driver/spi.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,8 @@ esp_err_t spi_set_mode(spi_host_t host, spi_mode_t *mode)
210210
SPI[host]->pin.slave_mode = true;
211211
SPI[host]->slave.slave_mode = true;
212212
SPI[host]->user.usr_miso_highpart = true;
213-
SPI[host]->ctrl2.mosi_delay_num = 1;
213+
// MOSI signals are delayed by APB_CLK(80MHz) mosi_delay_num cycles
214+
SPI[host]->ctrl2.mosi_delay_num = 2;
214215
SPI[host]->ctrl2.miso_delay_num = 0;
215216
SPI[host]->slave.wr_rd_sta_en = 1;
216217
SPI[host]->slave1.status_bitlen = 31;

examples/peripherals/spi_master/README.md

Lines changed: 18 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -51,68 +51,24 @@ See the Getting Started Guide for full steps to configure and use ESP-IDF to bui
5151
* LOG:
5252

5353
```
54-
I (214) spi_master_example: init gpio
55-
I (216) gpio: GPIO[4]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:1
56-
I (238) spi_master_example: init spi
57-
I (1238) spi_master_example: ------Master read------
58-
59-
I (1231) spi_master_example: addr: 0x0
60-
61-
I (1233) spi_master_example: read_data[0]: 0xaaaaaaaa
62-
63-
I (1249) spi_master_example: read_data[1]: 0xbbbbbbbb
64-
65-
I (1248) spi_master_example: read_data[2]: 0xcccccccc
66-
67-
I (1257) spi_master_example: read_data[3]: 0xdddddddd
68-
69-
I (1266) spi_master_example: read_data[4]: 0xeeeeeeee
70-
71-
I (1275) spi_master_example: read_data[5]: 0xffffffff
72-
73-
I (1284) spi_master_example: read_data[6]: 0xaaaabbbb
74-
75-
I (1293) spi_master_example: read_data[7]: 0x0
76-
77-
I (1301) spi_master_example: ------Master read------
78-
79-
I (1310) spi_master_example: addr: 0x1
80-
81-
I (1317) spi_master_example: read_data[0]: 0xaaaaaaaa
82-
83-
I (1326) spi_master_example: read_data[1]: 0xbbbbbbbb
84-
85-
I (1335) spi_master_example: read_data[2]: 0xcccccccc
86-
87-
I (1344) spi_master_example: read_data[3]: 0xdddddddd
88-
89-
I (1353) spi_master_example: read_data[4]: 0xeeeeeeee
90-
91-
I (1363) spi_master_example: read_data[5]: 0xffffffff
92-
93-
I (1372) spi_master_example: read_data[6]: 0xaaaabbbb
94-
95-
I (1381) spi_master_example: read_data[7]: 0x1
96-
97-
I (1399) spi_master_example: ------Master read------
98-
99-
I (1408) spi_master_example: addr: 0x2
100-
101-
I (1405) spi_master_example: read_data[0]: 0xaaaaaaaa
102-
103-
I (1414) spi_master_example: read_data[1]: 0xbbbbbbbb
104-
105-
I (1423) spi_master_example: read_data[2]: 0xcccccccc
106-
107-
I (1432) spi_master_example: read_data[3]: 0xdddddddd
108-
109-
I (1441) spi_master_example: read_data[4]: 0xeeeeeeee
110-
111-
I (1450) spi_master_example: read_data[5]: 0xffffffff
112-
113-
I (1469) spi_master_example: read_data[6]: 0xaaaabbbb
114-
115-
I (1478) spi_master_example: read_data[7]: 0x2
54+
I (516) spi_master_example: init gpio
55+
I (526) gpio: GPIO[4]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:1
56+
I (536) spi_master_example: init spi
57+
I (556) spi_master_example: Master wrote 3200 bytes in 4302 us
58+
I (656) spi_master_example: Master wrote 3200 bytes in 4519 us
59+
I (766) spi_master_example: Master wrote 3200 bytes in 4522 us
60+
I (866) spi_master_example: Master wrote 3200 bytes in 4520 us
61+
I (966) spi_master_example: Master wrote 3200 bytes in 4521 us
62+
I (1066) spi_master_example: Master wrote 3200 bytes in 4520 us
63+
I (1166) spi_master_example: Master wrote 3200 bytes in 4522 us
64+
I (1266) spi_master_example: Master wrote 3200 bytes in 4521 us
65+
I (1366) spi_master_example: Master wrote 3200 bytes in 4520 us
66+
I (1466) spi_master_example: Master wrote 3200 bytes in 4520 us
67+
I (1566) spi_master_example: Master wrote 3200 bytes in 4520 us
68+
I (1666) spi_master_example: Master wrote 3200 bytes in 4519 us
69+
I (1766) spi_master_example: Master wrote 3200 bytes in 4521 us
70+
I (1866) spi_master_example: Master wrote 3200 bytes in 4519 us
71+
I (1966) spi_master_example: Master wrote 3200 bytes in 4520 us
11672
```
11773

11874
* WAVE FORM:

examples/peripherals/spi_master/main/spi_master_example_main.c

Lines changed: 74 additions & 109 deletions
Original file line numberDiff line numberDiff line change
@@ -8,74 +8,78 @@
88
*/
99

1010
#include <stdio.h>
11-
11+
#include <sys/time.h>
1212
#include "freertos/FreeRTOS.h"
1313
#include "freertos/task.h"
14-
#include "freertos/queue.h"
14+
#include "freertos/semphr.h"
15+
#include "ringbuf.h"
1516

17+
#include "esp8266/spi_struct.h"
1618
#include "esp8266/gpio_struct.h"
19+
#include "esp_system.h"
1720
#include "esp_log.h"
1821

1922
#include "driver/gpio.h"
2023
#include "driver/spi.h"
2124

2225
static const char *TAG = "spi_master_example";
2326

24-
#define SPI_SLAVE_HANDSHARK_GPIO 4
25-
#define SPI_SLAVE_HANDSHARK_SEL (1ULL<<SPI_SLAVE_HANDSHARK_GPIO)
27+
#define SPI_MASTER_HANDSHARK_GPIO 4
28+
#define SPI_MASTER_HANDSHARK_SEL (1ULL<<SPI_MASTER_HANDSHARK_GPIO)
2629

27-
static xQueueHandle gpio_evt_queue = NULL;
30+
RingbufHandle_t spi_master_rx_ring_buf;
31+
struct timeval now;
2832

2933
static void gpio_isr_handler(void *arg)
3034
{
35+
int x;
3136
BaseType_t xHigherPriorityTaskWoken;
32-
uint32_t gpio_num = (uint32_t) arg;
33-
34-
xQueueSendFromISR(gpio_evt_queue, &gpio_num, &xHigherPriorityTaskWoken);
35-
36-
if (xHigherPriorityTaskWoken == pdTRUE) {
37-
taskYIELD();
38-
}
39-
}
40-
41-
void IRAM_ATTR spi_event_callback(int event, void *arg)
42-
{
43-
switch (event) {
44-
case SPI_INIT_EVENT: {
45-
46-
}
47-
break;
48-
49-
case SPI_TRANS_START_EVENT: {
50-
51-
}
52-
break;
53-
54-
case SPI_TRANS_DONE_EVENT: {
37+
uint32_t read_data[8];
5538

39+
if ((int)arg == SPI_MASTER_HANDSHARK_GPIO) {
40+
while (SPI1.cmd.usr);
41+
SPI1.user.usr_command = 1;
42+
SPI1.user.usr_addr = 1;
43+
SPI1.user.usr_mosi = 0;
44+
SPI1.user.usr_miso = 1;
45+
SPI1.user2.usr_command_bitlen = 8 - 1;
46+
SPI1.user1.usr_addr_bitlen = 32 - 1;
47+
SPI1.user1.usr_miso_bitlen = 32 * 8 - 1;
48+
SPI1.user2.usr_command_value = SPI_MASTER_READ_DATA_FROM_SLAVE_CMD;
49+
SPI1.addr = 0;
50+
SPI1.cmd.usr = 1;
51+
while (SPI1.cmd.usr);
52+
for (x = 0; x < 8; x++) {
53+
read_data[x] = SPI1.data_buf[x];
5654
}
57-
break;
58-
59-
case SPI_DEINIT_EVENT: {
55+
xRingbufferSendFromISR(spi_master_rx_ring_buf, (void *) read_data, sizeof(uint32_t) * 8, &xHigherPriorityTaskWoken);
6056

57+
if (xHigherPriorityTaskWoken == pdTRUE) {
58+
taskYIELD();
6159
}
62-
break;
6360
}
64-
6561
}
6662

6763
static void spi_master_write_slave_task(void *arg)
6864
{
69-
uint16_t cmd;
70-
uint32_t addr;
65+
int x;
7166
uint32_t write_data[8];
7267
spi_trans_t trans;
73-
uint32_t status;
68+
uint16_t cmd;
69+
uint32_t addr;
70+
uint64_t time_start, time_end;
7471

72+
trans.bits.val = 0;
73+
trans.bits.cmd = 8 * 1;
74+
trans.bits.addr = 32 * 1;
75+
trans.bits.mosi = 32 * 8;
76+
// Write data to the ESP8266 Slave use "SPI_MASTER_WRITE_DATA_TO_SLAVE_CMD" cmd
7577
trans.cmd = &cmd;
7678
trans.addr = &addr;
77-
addr = 0x0;
78-
write_data[0] = 0;
79+
trans.mosi = write_data;
80+
cmd = SPI_MASTER_WRITE_DATA_TO_SLAVE_CMD;
81+
addr = 0;
82+
write_data[0] = 1;
7983
write_data[1] = 0x11111111;
8084
write_data[2] = 0x22222222;
8185
write_data[3] = 0x33333333;
@@ -85,103 +89,55 @@ static void spi_master_write_slave_task(void *arg)
8589
write_data[7] = 0x77777777;
8690

8791
while (1) {
88-
if (addr % 50 == 0) {
89-
vTaskDelay(1000 / portTICK_RATE_MS);
90-
}
91-
92-
trans.miso = &status;
93-
trans.bits.val = 0;
94-
trans.bits.cmd = 8 * 1;
95-
trans.bits.miso = 32 * 1;
96-
// Read status from the ESP8266 Slave use "SPI_MASTER_READ_STATUS_FROM_SLAVE_CMD" cmd
97-
cmd = SPI_MASTER_READ_STATUS_FROM_SLAVE_CMD;
98-
// Get the slave status and send data when the slave is idle
99-
while (1) {
92+
gettimeofday(&now, NULL);
93+
time_start = now.tv_usec;
94+
for (x = 0;x < 100;x++) {
10095
spi_trans(HSPI_HOST, trans);
101-
if (status == true) {
102-
break;
103-
}
104-
vTaskDelay(10 / portTICK_RATE_MS);
96+
write_data[0]++;
10597
}
98+
gettimeofday(&now, NULL);
99+
time_end = now.tv_usec;
106100

107-
trans.mosi = write_data;
108-
trans.bits.val = 0;
109-
trans.bits.cmd = 8 * 1;
110-
trans.bits.addr = 32 * 1;
111-
trans.bits.mosi = 32 * 8;
112-
// Write data to the ESP8266 Slave use "SPI_MASTER_WRITE_DATA_TO_SLAVE_CMD" cmd
113-
cmd = SPI_MASTER_WRITE_DATA_TO_SLAVE_CMD;
114-
spi_trans(HSPI_HOST, trans);
115-
116-
addr++;
117-
write_data[0]++;
118-
vTaskDelay(10 / portTICK_RATE_MS);
101+
ESP_LOGI(TAG, "Master wrote 3200 bytes in %d us", (int)(time_end - time_start));
102+
vTaskDelay(100 / portTICK_RATE_MS);
119103
}
120104
}
121105

122106
static void spi_master_read_slave_task(void *arg)
123107
{
124-
int x;
125-
uint32_t io_num;
126-
uint16_t cmd;
127-
uint32_t addr;
128-
uint32_t read_data[8];
129-
spi_trans_t trans;
130-
uint32_t status = true;
131-
132-
trans.cmd = &cmd;
133-
// Write status to the ESP8266 Slave use "SPI_MASTER_WRITE_STATUS_TO_SLAVE_CMD" cmd
134-
cmd = SPI_MASTER_WRITE_STATUS_TO_SLAVE_CMD;
135-
trans.mosi = &status;
136-
trans.bits.val = 0;
137-
trans.bits.cmd = 8 * 1;
138-
trans.bits.mosi = 32 * 1;
139-
spi_trans(HSPI_HOST, trans);
140-
141-
trans.addr = &addr;
142-
trans.miso = read_data;
143-
trans.bits.val = 0;
144-
trans.bits.cmd = 8 * 1;
145-
trans.bits.addr = 32 * 1;
146-
trans.bits.miso = 32 * 8;
147-
// Read data from the ESP8266 Slave use "SPI_MASTER_READ_DATA_FROM_SLAVE_CMD" cmd
148-
cmd = SPI_MASTER_READ_DATA_FROM_SLAVE_CMD;
149-
addr = 0x0;
108+
uint32_t *read_data = NULL;
109+
uint32_t size;
150110

151111
while (1) {
152-
xQueueReceive(gpio_evt_queue, &io_num, portMAX_DELAY);
112+
read_data = (uint32_t *) xRingbufferReceive(spi_master_rx_ring_buf, &size, portMAX_DELAY);
153113

154-
if (SPI_SLAVE_HANDSHARK_GPIO != io_num) {
155-
break;
156-
}
157-
158-
spi_trans(HSPI_HOST, trans);
159-
ESP_LOGI(TAG, "------Master read------\n");
160-
ESP_LOGI(TAG, "addr: 0x%x\n", addr);
161-
162-
for (x = 0; x < 8; x++) {
163-
ESP_LOGI(TAG, "read_data[%d]: 0x%x\n", x, read_data[x]);
114+
if (read_data) {
115+
vRingbufferReturnItem(spi_master_rx_ring_buf, read_data);
116+
if (read_data[7] % 100 == 0) {
117+
vTaskDelay(100 / portTICK_RATE_MS);
118+
}
164119
}
165-
166-
addr++;
167120
}
168121
}
169122

170123
void app_main(void)
171124
{
172-
gpio_evt_queue = xQueueCreate(1, sizeof(uint32_t));
125+
spi_trans_t trans = {0};
126+
uint16_t cmd;
127+
uint32_t status = true;
128+
spi_master_rx_ring_buf = xRingbufferCreate(4096, RINGBUF_TYPE_NOSPLIT);
173129

174130
ESP_LOGI(TAG, "init gpio");
175131
gpio_config_t io_conf;
176132
io_conf.intr_type = GPIO_INTR_POSEDGE;
177133
io_conf.mode = GPIO_MODE_INPUT;
178-
io_conf.pin_bit_mask = SPI_SLAVE_HANDSHARK_SEL;
134+
io_conf.pin_bit_mask = SPI_MASTER_HANDSHARK_SEL;
179135
io_conf.pull_down_en = 0;
180136
io_conf.pull_up_en = 0;
181137
gpio_config(&io_conf);
182138

183139
gpio_install_isr_service(0);
184-
gpio_isr_handler_add(SPI_SLAVE_HANDSHARK_GPIO, gpio_isr_handler, (void *) SPI_SLAVE_HANDSHARK_GPIO);
140+
gpio_isr_handler_add(SPI_MASTER_HANDSHARK_GPIO, gpio_isr_handler, (void *) SPI_MASTER_HANDSHARK_GPIO);
185141

186142
ESP_LOGI(TAG, "init spi");
187143
spi_config_t spi_config;
@@ -197,9 +153,18 @@ void app_main(void)
197153
// Set the SPI clock frequency division factor
198154
spi_config.clk_div = SPI_10MHz_DIV;
199155
// Register SPI event callback function
200-
spi_config.event_cb = spi_event_callback;
156+
spi_config.event_cb = NULL;
201157
spi_init(HSPI_HOST, &spi_config);
202158

159+
// Write status to the ESP8266 Slave use "SPI_MASTER_WRITE_STATUS_TO_SLAVE_CMD" cmd
160+
cmd = SPI_MASTER_WRITE_STATUS_TO_SLAVE_CMD;
161+
trans.cmd = &cmd;
162+
trans.mosi = &status;
163+
trans.bits.val = 0;
164+
trans.bits.cmd = 8 * 1;
165+
trans.bits.mosi = 32 * 1;
166+
spi_trans(HSPI_HOST, trans);
167+
203168
// create spi_master_write_slave_task
204169
xTaskCreate(spi_master_write_slave_task, "spi_master_write_slave_task", 2048, NULL, 10, NULL);
205170

0 commit comments

Comments
 (0)