10
10
* 2017-07-28 armink fix auto reconnect feature
11
11
* 2018-12-24 zyh porting rw007 from rw009
12
12
* 2019-02-25 zyh porting rw007 to wlan
13
+ * 2020-02-28 shaoguoji add spi transfer retry
13
14
*/
14
15
#include <rtthread.h>
15
16
#include <string.h>
16
17
18
+ #define ABS_DIFF (a ,b ) (((a)>(b))?((a)-(b)):((b)-(a)))
19
+
17
20
#ifndef RW007_LOG_LEVEL
18
21
#define RW007_LOG_LEVEL DBG_LOG
19
22
#endif
@@ -32,19 +35,33 @@ static struct rt_event spi_wifi_data_event;
32
35
33
36
static rt_err_t spi_wifi_transfer (struct rw007_spi * dev )
34
37
{
38
+ static const struct spi_data_packet * pre_data_packet ;
39
+
35
40
struct spi_cmd_request cmd ;
36
41
struct spi_response resp ;
42
+ rt_uint32_t pre_tick = 0 ;
43
+ rt_uint32_t cur_tick = 0 ;
44
+ rt_uint32_t timeout = 10 ;
37
45
38
46
rt_err_t result ;
39
47
const struct spi_data_packet * data_packet = RT_NULL ;
40
48
struct rt_spi_device * rt_spi_device = dev -> spi_device ;
41
49
uint8_t * rx_buffer = rt_mp_alloc (& dev -> spi_rx_mp , RT_WAITING_NO );
50
+
42
51
/* Disable INT Pin interrupt */
43
52
spi_wifi_int_cmd (0 );
44
53
45
- while (spi_wifi_is_busy ())
54
+ /* Wait for busy */
55
+ pre_tick = rt_tick_get ();
56
+ while ((spi_wifi_is_busy ()))
46
57
{
47
58
/* 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
+ }
48
65
}
49
66
50
67
/* Clear cmd */
@@ -61,21 +78,44 @@ static rt_err_t spi_wifi_transfer(struct rw007_spi *dev)
61
78
cmd .flag |= CMD_FLAG_MRDY ;
62
79
}
63
80
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 )
70
82
{
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 ;
72
98
}
73
99
74
100
/* Stage 1: Send command to rw007 */
75
101
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 ()))
77
111
{
78
112
/* 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
+ }
79
119
}
80
120
81
121
/* Stage 2: Receive response from rw007 and transmit data */
@@ -99,8 +139,8 @@ static rt_err_t spi_wifi_transfer(struct rw007_spi *dev)
99
139
/* Check response's magic word */
100
140
if ((resp .magic1 != RESP_MAGIC1 ) || (resp .magic2 != RESP_MAGIC2 ))
101
141
{
102
- resp . S2M_len = 0 ;
103
- goto _bad_resp_magic ;
142
+ result = RT_EINVAL ;
143
+ goto _exit ;
104
144
}
105
145
106
146
/* Check rw007's data ready flag */
@@ -120,7 +160,7 @@ static rt_err_t spi_wifi_transfer(struct rw007_spi *dev)
120
160
if (resp .S2M_len > max_data_len )
121
161
max_data_len = resp .S2M_len ;
122
162
}
123
- _bad_resp_magic :
163
+
124
164
/* Setup message */
125
165
if (!resp .S2M_len && rx_buffer )
126
166
{
@@ -136,31 +176,46 @@ static rt_err_t spi_wifi_transfer(struct rw007_spi *dev)
136
176
/* Transmit data */
137
177
rt_spi_device -> bus -> ops -> xfer (rt_spi_device , & message );
138
178
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 ()))
144
182
{
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
+ }
153
190
}
154
191
}
155
- /* Enable INT Pin interrupt */
156
- spi_wifi_int_cmd ( 1 ) ;
192
+
193
+ pre_data_packet = RT_NULL ;
157
194
158
195
if ((cmd .M2S_len == 0 ) && (resp .S2M_len == 0 ))
159
196
{
160
- return - RT_ERROR ;
197
+ result = - RT_EEMPTY ;
161
198
}
199
+ _exit :
200
+ /* End a SPI transmit */
201
+ rt_spi_release_bus (rt_spi_device );
162
202
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 ;
164
219
}
165
220
166
221
static void wifi_data_process_thread_entry (void * parameter )
@@ -250,6 +305,7 @@ static void spi_wifi_data_thread_entry(void *parameter)
250
305
{
251
306
rt_uint32_t e ;
252
307
rt_err_t result ;
308
+ rt_uint32_t retry_count = 0 ;
253
309
254
310
while (1 )
255
311
{
@@ -265,12 +321,29 @@ static void spi_wifi_data_thread_entry(void *parameter)
265
321
266
322
/* transfer */
267
323
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
+ }
268
338
269
- /* continue transfer once */
270
- if (result == RT_EOK )
339
+ if (retry_count == 0 )
271
340
{
272
- rt_event_send (& spi_wifi_data_event , 1 );
341
+ retry_count = SPI_MAX_RETRY_COUNT ;
342
+ continue ;
273
343
}
344
+
345
+ /* continue transfer once */
346
+ rt_event_send (& spi_wifi_data_event , 1 );
274
347
}
275
348
}
276
349
@@ -604,7 +677,7 @@ rt_err_t rt_hw_wifi_init(const char *spi_device_name)
604
677
struct rt_spi_configuration cfg ;
605
678
cfg .data_width = 8 ;
606
679
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 */
608
681
rt_spi_configure (rw007_spi .spi_device , & cfg );
609
682
}
610
683
0 commit comments