Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 73bf28b

Browse files
committed
Merge branch 'feature/hspi_test' into 'master'
feat(spi): fix some bugs and restructure the spi driver and the demo See merge request sdk/ESP8266_RTOS_SDK!1113
2 parents 1e509f6 + 916906d commit 73bf28b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+1879
-660
lines changed

components/esp8266/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ else()
4646
"driver/i2s.c"
4747
"driver/pwm.c"
4848
"driver/spi.c"
49+
"driver/hspi_logic_layer.c"
4950
"driver/uart.c"
5051
"driver/ir_tx.c"
5152
"driver/ir_rx.c"

components/esp8266/Kconfig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -627,3 +627,12 @@ config ESP8266_PHY_MAX_WIFI_TX_POWER
627627

628628
endmenu # PHY
629629

630+
menu HSPI
631+
config ESP8266_HSPI_HIGH_THROUGHPUT
632+
bool "Do some optimization to improve throughput"
633+
default n
634+
help
635+
If enable this configuration, some spi api will be placed into iram.
636+
And it will reduce iram memory.
637+
endmenu # Driver
638+
Lines changed: 278 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,278 @@
1+
2+
#include <stdio.h>
3+
#include <string.h>
4+
#include <sys/time.h>
5+
#include "freertos/FreeRTOS.h"
6+
#include "freertos/task.h"
7+
#include "freertos/semphr.h"
8+
#include "freertos/event_groups.h"
9+
#include "freertos/stream_buffer.h"
10+
#include "ringbuf.h"
11+
12+
#include "esp8266/spi_struct.h"
13+
#include "esp8266/gpio_struct.h"
14+
#include "esp_system.h"
15+
#include "esp_log.h"
16+
17+
#include "driver/gpio.h"
18+
#include "driver/spi.h"
19+
#include "driver/hspi_logic_layer.h"
20+
21+
static const char *TAG = "hspi_logic";
22+
#define SPI_CHECK(a, str, ret_val) \
23+
do { \
24+
if (!(a)) { \
25+
ESP_LOGE(TAG,"%s(%d): %s", __FUNCTION__, __LINE__, str); \
26+
return (ret_val); \
27+
} \
28+
} while(0)
29+
30+
typedef struct {
31+
gpio_num_t trigger_pin;
32+
uint8_t trigger_level;
33+
bool is_sending;
34+
bool is_blocking_recv;
35+
uint32_t sending_len;
36+
uint32_t recving_len;
37+
StreamBufferHandle_t* tx_buffer;
38+
StreamBufferHandle_t* rx_buffer;
39+
40+
SemaphoreHandle_t semphor;
41+
spi_event_callback_t event_cb;
42+
} spi_logic_device_t;
43+
44+
static spi_logic_device_t * spi_logic_device;
45+
46+
static void IRAM_ATTR hspi_slave_event_callback(int event, void *arg)
47+
{
48+
int x;
49+
BaseType_t xHigherPriorityTaskWoken;
50+
uint32_t status;
51+
uint32_t trans_done;
52+
uint32_t data[16];
53+
spi_trans_t trans;
54+
uint16_t cmd = 0;
55+
bool trigger_flag = false;
56+
57+
switch (event) {
58+
case SPI_TRANS_DONE_EVENT: {
59+
gpio_set_level(spi_logic_device->trigger_pin, !spi_logic_device->trigger_level);
60+
trans_done = *(uint32_t *)arg;
61+
if (trans_done & SPI_SLV_RD_BUF_DONE) {
62+
if (spi_logic_device->sending_len == 0) {
63+
spi_logic_device->is_sending = false;
64+
spi_logic_device->sending_len = xStreamBufferBytesAvailable(spi_logic_device->tx_buffer);
65+
if (spi_logic_device->sending_len > 0) {
66+
spi_slave_set_status(HSPI_HOST, (uint32_t*)&spi_logic_device->sending_len);
67+
spi_logic_device->is_sending = true;
68+
trigger_flag = true;
69+
}
70+
} else {
71+
memset(&trans, 0x0, sizeof(trans));
72+
trans.cmd = &cmd;
73+
trans.addr = NULL;
74+
trans.bits.val = 0;
75+
// In Slave mode, spi cmd must be longer than 3 bits and shorter than 16 bits
76+
trans.bits.cmd = 8 * 1;
77+
// In Slave mode, spi addr must be longer than 1 bits and shorter than 32 bits
78+
trans.bits.addr = 8 * 1;
79+
trans.bits.mosi = 0;
80+
trans.miso = data;
81+
trans.bits.miso = xStreamBufferReceiveFromISR(spi_logic_device->tx_buffer, data, 64, &xHigherPriorityTaskWoken);
82+
if (trans.bits.miso != 0) {
83+
spi_logic_device->sending_len -= trans.bits.miso;
84+
trans.bits.miso <<= 3;
85+
spi_trans(HSPI_HOST, &trans);
86+
trigger_flag = true;;
87+
}
88+
}
89+
}
90+
91+
if (trans_done & SPI_SLV_WR_BUF_DONE) {
92+
uint32_t len = spi_logic_device->recving_len;
93+
if (len > 64) {
94+
len = 64;
95+
}
96+
97+
if (len > 0) {
98+
for (x = 0; x < 16; x++) {
99+
data[x] = SPI1.data_buf[x];
100+
}
101+
xStreamBufferSendFromISR(spi_logic_device->rx_buffer, (void *) data, len, &xHigherPriorityTaskWoken);
102+
spi_logic_device->recving_len -= len;
103+
} else {
104+
ets_printf("remained %d\r\n", len);
105+
}
106+
107+
if (xStreamBufferSpacesAvailable(spi_logic_device->rx_buffer) >= 64) {
108+
trigger_flag = true;
109+
} else {
110+
spi_logic_device->is_blocking_recv = true;
111+
}
112+
}
113+
114+
if (trans_done & SPI_SLV_WR_STA_DONE) {
115+
spi_slave_get_status(HSPI_HOST, &status);
116+
spi_logic_device->recving_len = status;
117+
uint32_t tx_size = xStreamBufferBytesAvailable(spi_logic_device->tx_buffer);
118+
119+
if (spi_logic_device->recving_len > 0) {
120+
trigger_flag = true;
121+
} else if (tx_size > 0) {
122+
if (spi_logic_device->is_sending == false) {
123+
spi_slave_set_status(HSPI_HOST, &tx_size);
124+
}
125+
trigger_flag = true;
126+
}
127+
}
128+
129+
if (trans_done & SPI_SLV_RD_STA_DONE) {
130+
memset(&trans, 0x0, sizeof(trans));
131+
trans.cmd = &cmd;
132+
trans.addr = NULL;
133+
trans.bits.val = 0;
134+
// In Slave mode, spi cmd must be longer than 3 bits and shorter than 16 bits
135+
trans.bits.cmd = 8 * 1;
136+
// In Slave mode, spi addr must be longer than 1 bits and shorter than 32 bits
137+
trans.bits.addr = 8 * 1;
138+
trans.bits.mosi = 0;
139+
trans.miso = data;
140+
trans.bits.miso = xStreamBufferReceiveFromISR(spi_logic_device->tx_buffer, data, 64, &xHigherPriorityTaskWoken);
141+
if (trans.bits.miso != 0) {
142+
spi_logic_device->sending_len -= trans.bits.miso;
143+
trans.bits.miso <<= 3;
144+
spi_trans(HSPI_HOST, &trans);
145+
trigger_flag = true;
146+
}
147+
}
148+
149+
if (trigger_flag) {
150+
gpio_set_level(spi_logic_device->trigger_pin, spi_logic_device->trigger_level);
151+
}
152+
153+
if (spi_logic_device->event_cb) {
154+
spi_logic_device->event_cb(event, arg);
155+
}
156+
157+
if (xHigherPriorityTaskWoken == pdTRUE) {
158+
taskYIELD();
159+
}
160+
}
161+
break;
162+
case SPI_DEINIT_EVENT: {
163+
}
164+
break;
165+
}
166+
167+
}
168+
169+
uint32_t hspi_slave_logic_read_data(uint8_t*data, uint32_t len, TickType_t xTicksToWait)
170+
{
171+
uint32_t ret = 0;
172+
173+
ret = xStreamBufferReceive(spi_logic_device->rx_buffer, data, len, xTicksToWait);
174+
if (spi_logic_device->is_blocking_recv) {
175+
if (xStreamBufferBytesAvailable(spi_logic_device->rx_buffer) > 64) {
176+
gpio_set_level(spi_logic_device->trigger_pin, spi_logic_device->trigger_level);
177+
spi_logic_device->is_blocking_recv = false;
178+
}
179+
}
180+
181+
return ret;
182+
}
183+
184+
uint32_t hspi_slave_logic_write_data(uint8_t*data, uint32_t len, TickType_t xTicksToWait)
185+
{
186+
uint32_t ret = 0;
187+
uint32_t avail_spaces = 0;
188+
189+
if (!spi_logic_device->is_sending) {
190+
portENTER_CRITICAL();
191+
avail_spaces = xStreamBufferSpacesAvailable(spi_logic_device->tx_buffer);
192+
if (avail_spaces > len) {
193+
avail_spaces = len;
194+
}
195+
ret = xStreamBufferSend(spi_logic_device->tx_buffer, data, avail_spaces, xTicksToWait); //
196+
spi_logic_device->sending_len = xStreamBufferBytesAvailable(spi_logic_device->tx_buffer);
197+
spi_slave_set_status(HSPI_HOST, (uint32_t*)&spi_logic_device->sending_len);
198+
spi_logic_device->is_sending = true;
199+
gpio_set_level(spi_logic_device->trigger_pin, spi_logic_device->trigger_level);
200+
portEXIT_CRITICAL();
201+
}
202+
203+
if (ret < len) {
204+
ret += xStreamBufferSend(spi_logic_device->tx_buffer, data + ret, len - ret, xTicksToWait);
205+
}
206+
207+
return ret;
208+
}
209+
210+
esp_err_t hspi_slave_logic_device_create(gpio_num_t trigger_pin, uint32_t trigger_level,uint32_t tx_buffer_size, uint32_t rx_buffer_size)
211+
{
212+
SPI_CHECK(GPIO_IS_VALID_GPIO(trigger_pin), "gpio num error", ESP_ERR_INVALID_ARG);
213+
SPI_CHECK(tx_buffer_size != 0, "tx buffer error", ESP_ERR_INVALID_ARG);
214+
SPI_CHECK(rx_buffer_size != 0, "rx buffer error", ESP_ERR_INVALID_ARG);
215+
216+
gpio_config_t io_conf;
217+
218+
if (spi_logic_device) {
219+
hspi_slave_logic_device_delete();
220+
}
221+
spi_logic_device = (spi_logic_device_t*)malloc(sizeof(spi_logic_device_t));
222+
assert(spi_logic_device);
223+
224+
memset(spi_logic_device, 0x0, sizeof(spi_logic_device_t));
225+
spi_logic_device->tx_buffer = xStreamBufferCreate(tx_buffer_size,1);
226+
if (!spi_logic_device->tx_buffer) {
227+
free(spi_logic_device);
228+
spi_logic_device = NULL;
229+
return ESP_ERR_NO_MEM;
230+
}
231+
232+
spi_logic_device->rx_buffer = xStreamBufferCreate(rx_buffer_size,1);
233+
if (!spi_logic_device->rx_buffer) {
234+
vStreamBufferDelete(spi_logic_device->tx_buffer);
235+
spi_logic_device->tx_buffer = NULL;
236+
237+
free(spi_logic_device);
238+
spi_logic_device = NULL;
239+
return ESP_ERR_NO_MEM;
240+
}
241+
242+
spi_logic_device->trigger_pin = trigger_pin;
243+
spi_logic_device->trigger_level = (trigger_level==1)?1:0;
244+
245+
memset(&io_conf, 0x0, sizeof(io_conf));
246+
io_conf.intr_type = GPIO_INTR_DISABLE;
247+
io_conf.mode = GPIO_MODE_OUTPUT;
248+
io_conf.pin_bit_mask = (1ULL << trigger_pin);
249+
io_conf.pull_down_en = 0;
250+
io_conf.pull_up_en = 0;
251+
gpio_config(&io_conf);
252+
gpio_set_level(trigger_pin, !spi_logic_device->trigger_level);
253+
254+
spi_get_event_callback(HSPI_HOST, &spi_logic_device->event_cb);
255+
256+
spi_event_callback_t event_cb = hspi_slave_event_callback;
257+
spi_set_event_callback(HSPI_HOST, &event_cb);
258+
259+
return ESP_OK;
260+
}
261+
262+
esp_err_t hspi_slave_logic_device_delete(void)
263+
{
264+
if (spi_logic_device == NULL) {
265+
return ESP_ERR_INVALID_STATE;
266+
}
267+
268+
vStreamBufferDelete(spi_logic_device->tx_buffer);
269+
spi_logic_device->tx_buffer = NULL;
270+
271+
vStreamBufferDelete(spi_logic_device->rx_buffer);
272+
spi_logic_device->rx_buffer = NULL;
273+
274+
free(spi_logic_device);
275+
spi_logic_device = NULL;
276+
277+
return ESP_OK;
278+
}

0 commit comments

Comments
 (0)