Skip to content

Commit 9e8a40c

Browse files
authored
Merge pull request #11 from shaoguoji/add_spi_retry
[add]增加spi错误重传机制
2 parents 9c72e5b + 7e8c080 commit 9e8a40c

File tree

2 files changed

+113
-33
lines changed

2 files changed

+113
-33
lines changed

inc/spi_wifi_rw007.h

+7
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
* Date Author Notes
88
* 2014-07-31 aozima the first version
99
* 2014-09-18 aozima update command & response.
10+
* 2020-02-28 shaoguoji add spi transfer retry
1011
*/
1112

1213
#ifndef SPI_WIFI_H_INCLUDED
@@ -24,6 +25,12 @@ struct spi_cmd_request
2425
uint32_t magic2;
2526
};
2627

28+
#ifndef RW007_SPI_MAX_HZ
29+
#define RW007_SPI_MAX_HZ 30000000
30+
#endif
31+
32+
#define SPI_MAX_RETRY_COUNT 5
33+
2734
#define CMD_MAGIC1 (0x67452301)
2835
#define CMD_MAGIC2 (0xEFCDAB89)
2936

src/spi_wifi_rw007.c

+106-33
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,13 @@
1010
* 2017-07-28 armink fix auto reconnect feature
1111
* 2018-12-24 zyh porting rw007 from rw009
1212
* 2019-02-25 zyh porting rw007 to wlan
13+
* 2020-02-28 shaoguoji add spi transfer retry
1314
*/
1415
#include <rtthread.h>
1516
#include <string.h>
1617

18+
#define ABS_DIFF(a,b) (((a)>(b))?((a)-(b)):((b)-(a)))
19+
1720
#ifndef RW007_LOG_LEVEL
1821
#define RW007_LOG_LEVEL DBG_LOG
1922
#endif
@@ -32,19 +35,33 @@ static struct rt_event spi_wifi_data_event;
3235

3336
static rt_err_t spi_wifi_transfer(struct rw007_spi *dev)
3437
{
38+
static const struct spi_data_packet *pre_data_packet;
39+
3540
struct spi_cmd_request cmd;
3641
struct spi_response resp;
42+
rt_uint32_t pre_tick = 0;
43+
rt_uint32_t cur_tick = 0;
44+
rt_uint32_t timeout = 10;
3745

3846
rt_err_t result;
3947
const struct spi_data_packet *data_packet = RT_NULL;
4048
struct rt_spi_device *rt_spi_device = dev->spi_device;
4149
uint8_t * rx_buffer = rt_mp_alloc(&dev->spi_rx_mp, RT_WAITING_NO);
50+
4251
/* Disable INT Pin interrupt */
4352
spi_wifi_int_cmd(0);
4453

45-
while (spi_wifi_is_busy())
54+
/* Wait for busy */
55+
pre_tick = rt_tick_get();
56+
while ((spi_wifi_is_busy()))
4657
{
4758
/* wait for idel */
59+
cur_tick = rt_tick_get();
60+
if (ABS_DIFF(cur_tick, pre_tick) >= timeout)
61+
{
62+
result = RT_ETIMEOUT;
63+
goto _exit;
64+
}
4865
}
4966

5067
/* Clear cmd */
@@ -61,21 +78,44 @@ static rt_err_t spi_wifi_transfer(struct rw007_spi *dev)
6178
cmd.flag |= CMD_FLAG_MRDY;
6279
}
6380

64-
/* Try get data to send to rw007 */
65-
result = rt_mb_recv(&dev->spi_tx_mb,
66-
(rt_ubase_t *)&data_packet,
67-
0);
68-
/* Set length for master to slave when data ready*/
69-
if ((result == RT_EOK) && (data_packet != RT_NULL) && (data_packet->data_len > 0))
81+
if (pre_data_packet)
7082
{
71-
cmd.M2S_len = data_packet->data_len + member_offset(struct spi_data_packet, buffer);
83+
data_packet = pre_data_packet; // Retry case, use previous saved data
84+
}
85+
else
86+
{
87+
/* Try get data to send to rw007 */
88+
result = rt_mb_recv(&dev->spi_tx_mb,
89+
(rt_ubase_t *)&data_packet,
90+
0);
91+
/* Set length for master to slave when data ready*/
92+
if ((result == RT_EOK) && (data_packet != RT_NULL) && (data_packet->data_len > 0))
93+
{
94+
cmd.M2S_len = data_packet->data_len + member_offset(struct spi_data_packet, buffer);
95+
pre_data_packet = data_packet; // update previous data
96+
}
97+
result = RT_EOK;
7298
}
7399

74100
/* Stage 1: Send command to rw007 */
75101
rt_spi_send(rt_spi_device, &cmd, sizeof(cmd));
76-
while (spi_wifi_is_busy())
102+
103+
/* Wait for busy */
104+
if (!spi_wifi_is_busy())
105+
{
106+
result = -RT_EIO;
107+
goto _exit;
108+
}
109+
pre_tick = rt_tick_get();
110+
while ((spi_wifi_is_busy()))
77111
{
78112
/* wait for idel */
113+
cur_tick = rt_tick_get();
114+
if (ABS_DIFF(cur_tick, pre_tick) >= timeout)
115+
{
116+
result = -RT_ETIMEOUT;
117+
goto _exit;
118+
}
79119
}
80120

81121
/* Stage 2: Receive response from rw007 and transmit data */
@@ -99,8 +139,8 @@ static rt_err_t spi_wifi_transfer(struct rw007_spi *dev)
99139
/* Check response's magic word */
100140
if ((resp.magic1 != RESP_MAGIC1) || (resp.magic2 != RESP_MAGIC2))
101141
{
102-
resp.S2M_len = 0;
103-
goto _bad_resp_magic;
142+
result = RT_EINVAL;
143+
goto _exit;
104144
}
105145

106146
/* Check rw007's data ready flag */
@@ -120,7 +160,7 @@ static rt_err_t spi_wifi_transfer(struct rw007_spi *dev)
120160
if (resp.S2M_len > max_data_len)
121161
max_data_len = resp.S2M_len;
122162
}
123-
_bad_resp_magic:
163+
124164
/* Setup message */
125165
if(!resp.S2M_len && rx_buffer)
126166
{
@@ -136,31 +176,46 @@ static rt_err_t spi_wifi_transfer(struct rw007_spi *dev)
136176
/* Transmit data */
137177
rt_spi_device->bus->ops->xfer(rt_spi_device, &message);
138178

139-
/* End a SPI transmit */
140-
rt_spi_release_bus(rt_spi_device);
141-
142-
/* Free send data space */
143-
if (data_packet)
179+
/* Wait for busy */
180+
pre_tick = rt_tick_get();
181+
while ((spi_wifi_is_busy()))
144182
{
145-
rt_mp_free((void *)data_packet);
146-
data_packet = RT_NULL;
147-
}
148-
149-
/* Parse recevied data */
150-
if(rx_buffer)
151-
{
152-
rt_mb_send(&dev->spi_rx_mb, (rt_ubase_t)rx_buffer);
183+
/* wait for idel */
184+
cur_tick = rt_tick_get();
185+
if (ABS_DIFF(cur_tick, pre_tick) >= timeout)
186+
{
187+
result = -RT_ETIMEOUT;
188+
goto _exit;
189+
}
153190
}
154191
}
155-
/* Enable INT Pin interrupt */
156-
spi_wifi_int_cmd(1);
192+
193+
pre_data_packet = RT_NULL;
157194

158195
if ((cmd.M2S_len == 0) && (resp.S2M_len == 0))
159196
{
160-
return -RT_ERROR;
197+
result = -RT_EEMPTY;
161198
}
199+
_exit:
200+
/* End a SPI transmit */
201+
rt_spi_release_bus(rt_spi_device);
162202

163-
return RT_EOK;
203+
/* Free send data space */
204+
if (data_packet)
205+
{
206+
rt_mp_free((void *)data_packet);
207+
data_packet = RT_NULL;
208+
}
209+
210+
/* Parse recevied data */
211+
if(rx_buffer)
212+
{
213+
rt_mb_send(&dev->spi_rx_mb, (rt_ubase_t)rx_buffer);
214+
}
215+
/* Enable INT Pin interrupt */
216+
spi_wifi_int_cmd(1);
217+
218+
return result;
164219
}
165220

166221
static void wifi_data_process_thread_entry(void *parameter)
@@ -250,6 +305,7 @@ static void spi_wifi_data_thread_entry(void *parameter)
250305
{
251306
rt_uint32_t e;
252307
rt_err_t result;
308+
rt_uint32_t retry_count = 0;
253309

254310
while (1)
255311
{
@@ -265,12 +321,29 @@ static void spi_wifi_data_thread_entry(void *parameter)
265321

266322
/* transfer */
267323
result = spi_wifi_transfer(&rw007_spi);
324+
325+
/* result processing */
326+
switch (result)
327+
{
328+
case RT_EOK:
329+
retry_count = SPI_MAX_RETRY_COUNT;
330+
break;
331+
case RT_ETIMEOUT:
332+
case RT_EIO:
333+
retry_count--;
334+
break;
335+
default:
336+
continue;
337+
}
268338

269-
/* continue transfer once */
270-
if (result == RT_EOK)
339+
if (retry_count == 0)
271340
{
272-
rt_event_send(&spi_wifi_data_event, 1);
341+
retry_count = SPI_MAX_RETRY_COUNT;
342+
continue;
273343
}
344+
345+
/* continue transfer once */
346+
rt_event_send(&spi_wifi_data_event, 1);
274347
}
275348
}
276349

@@ -604,7 +677,7 @@ rt_err_t rt_hw_wifi_init(const char *spi_device_name)
604677
struct rt_spi_configuration cfg;
605678
cfg.data_width = 8;
606679
cfg.mode = RT_SPI_MODE_0 | RT_SPI_MSB; /* SPI Compatible: Mode 0. */
607-
cfg.max_hz = 30 * 1000000; /* 15M 007 max 30M */
680+
cfg.max_hz = RW007_SPI_MAX_HZ; /* 15M 007 max 30M */
608681
rt_spi_configure(rw007_spi.spi_device, &cfg);
609682
}
610683

0 commit comments

Comments
 (0)