1 /*
2 * COPYRIGHT (C) 2018, Real-Thread Information Technology Ltd
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2014-07-31 aozima the first version
9 * 2014-09-18 aozima update command & response.
10 * 2017-07-28 armink fix auto reconnect feature
11 */
12
13 #include <rtthread.h>
14 #include <drivers/spi.h>
15
16 #include <netif/ethernetif.h>
17 #include <netif/etharp.h>
18 #include <lwip/icmp.h>
19 #include "lwipopts.h"
20
21 #define WIFI_DEBUG_ON
22 // #define ETH_RX_DUMP
23 // #define ETH_TX_DUMP
24
25 #ifdef WIFI_DEBUG_ON
26 #define WIFI_DEBUG rt_kprintf("[RW009] ");rt_kprintf
27 //#define SPI_DEBUG rt_kprintf("[SPI] ");rt_kprintf
28 #define SPI_DEBUG(...)
29 #else
30 #define WIFI_DEBUG(...)
31 #define SPI_DEBUG(...)
32 #endif /* #ifdef WIFI_DEBUG_ON */
33
34 /********************************* RW009 **************************************/
35 #include "spi_wifi_rw009.h"
36
37 /* tools */
38 #define node_entry(node, type, member) \
39 ((type *)((char *)(node) - (unsigned long)(&((type *)0)->member)))
40 #define member_offset(type, member) \
41 ((unsigned long)(&((type *)0)->member))
42
43 #define MAX_SPI_PACKET_SIZE (member_offset(struct spi_data_packet, buffer) + SPI_MAX_DATA_LEN)
44 #define MAX_SPI_BUFFER_SIZE (sizeof(struct spi_response) + MAX_SPI_PACKET_SIZE)
45 #define MAX_ADDR_LEN 6
46
47 struct rw009_wifi
48 {
49 /* inherit from ethernet device */
50 struct eth_device parent;
51
52 struct rt_spi_device *rt_spi_device;
53
54 /* interface address info. */
55 rt_uint8_t dev_addr[MAX_ADDR_LEN]; /* hw address */
56 rt_uint8_t active;
57
58 struct rt_mempool spi_tx_mp;
59 struct rt_mempool spi_rx_mp;
60
61 struct rt_mailbox spi_tx_mb;
62 struct rt_mailbox eth_rx_mb;
63
64 int spi_tx_mb_pool[SPI_TX_POOL_SIZE + 1];
65 int eth_rx_mb_pool[SPI_RX_POOL_SIZE + 1];
66
67 int rw009_cmd_mb_pool[3];
68 struct rt_mailbox rw009_cmd_mb;
69 uint32_t last_cmd;
70
71 ALIGN(4)
72 rt_uint8_t spi_tx_mempool[(sizeof(struct spi_data_packet) + 4) * SPI_TX_POOL_SIZE];
73 ALIGN(4)
74 rt_uint8_t spi_rx_mempool[(sizeof(struct spi_data_packet) + 4) * SPI_RX_POOL_SIZE];
75
76 ALIGN(4)
77 uint8_t spi_hw_rx_buffer[MAX_SPI_BUFFER_SIZE];
78
79 /* status for RW009 */
80 rw009_ap_info ap_info; /* AP info for conn. */
81 rw009_ap_info *ap_scan; /* AP list for SCAN. */
82 uint32_t ap_scan_count;
83 };
84 static struct rw009_wifi rw009_wifi_device;
85 static struct rt_event spi_wifi_data_event;
86
resp_handler(struct rw009_wifi * wifi_device,struct rw009_resp * resp)87 static void resp_handler(struct rw009_wifi *wifi_device, struct rw009_resp *resp)
88 {
89 struct rw009_resp *resp_return = RT_NULL;
90
91 switch (resp->cmd)
92 {
93 case RW009_CMD_INIT:
94 WIFI_DEBUG("resp_handler RW009_CMD_INIT\n");
95 resp_return = (struct rw009_resp *)rt_malloc(member_offset(struct rw009_resp, resp) + sizeof(rw009_resp_init)); //TODO:
96 if(resp_return == RT_NULL) break;
97 memcpy(resp_return, resp, member_offset(struct rw009_resp, resp) + sizeof(rw009_resp_init));
98
99 WIFI_DEBUG("sn:%-*.*s\n", sizeof(resp->resp.init.sn), sizeof(resp->resp.init.sn), resp->resp.init.sn);
100 WIFI_DEBUG("version:%-*.*s\n", sizeof(resp->resp.init.version), sizeof(resp->resp.init.version), resp->resp.init.version);
101
102 rt_memcpy(wifi_device->dev_addr, resp->resp.init.mac, 6);
103 break;
104
105 case RW009_CMD_SCAN:
106 if( resp->len == sizeof(rw009_ap_info) )
107 {
108 rw009_ap_info *ap_scan = rt_realloc(wifi_device->ap_scan, sizeof(rw009_ap_info) * (wifi_device->ap_scan_count + 1) );
109 if(ap_scan != RT_NULL)
110 {
111 memcpy( &ap_scan[wifi_device->ap_scan_count], &resp->resp.ap_info, sizeof(rw009_ap_info) );
112
113 //dump
114 if(1)
115 {
116 #ifdef WIFI_DEBUG_ON
117 rw009_ap_info *ap_info = &resp->resp.ap_info;
118 WIFI_DEBUG("SCAN SSID:%-32.32s\n", ap_info->ssid);
119 WIFI_DEBUG("SCAN BSSID:%02X-%02X-%02X-%02X-%02X-%02X\n",
120 ap_info->bssid[0],
121 ap_info->bssid[1],
122 ap_info->bssid[2],
123 ap_info->bssid[3],
124 ap_info->bssid[4],
125 ap_info->bssid[5]);
126 WIFI_DEBUG("SCAN rssi:%ddBm\n", ap_info->rssi);
127 WIFI_DEBUG("SCAN rate:%dMbps\n", ap_info->max_data_rate/1000);
128 WIFI_DEBUG("SCAN channel:%d\n", ap_info->channel);
129 WIFI_DEBUG("SCAN security:%08X\n\n", ap_info->security);
130 #endif /* WIFI_DEBUG_ON */
131 }
132
133 wifi_device->ap_scan_count++;
134 wifi_device->ap_scan = ap_scan;
135 }
136
137 return; /* wait for next ap */
138 }
139 break;
140 case RW009_CMD_JOIN:
141 case RW009_CMD_EASY_JOIN:
142 WIFI_DEBUG("resp_handler RW009_CMD_EASY_JOIN\n");
143 resp_return = (struct rw009_resp *)rt_malloc(member_offset(struct rw009_resp, resp) + sizeof(rw009_resp_join)); //TODO:
144 if(resp_return == RT_NULL) break;
145 memcpy(resp_return, resp, member_offset(struct rw009_resp, resp) + sizeof(rw009_resp_join));
146
147 if( resp->result == 0 )
148 {
149 memcpy(&wifi_device->ap_info, &resp_return->resp.ap_info, sizeof(rw009_resp_join));
150 wifi_device->active = 1;
151 eth_device_linkchange(&wifi_device->parent, RT_TRUE);
152 }
153 else
154 {
155 wifi_device->active = 1;
156 eth_device_linkchange(&wifi_device->parent, RT_FALSE);
157 WIFI_DEBUG("RW009_CMD_EASY_JOIN result: %d\n", resp->result );
158 }
159
160 //dupm
161 if(1)
162 {
163 #ifdef WIFI_DEBUG_ON
164 rw009_ap_info *ap_info = &resp->resp.ap_info;
165 WIFI_DEBUG("JOIN SSID:%-32.32s\n", ap_info->ssid);
166 WIFI_DEBUG("JOIN BSSID:%02X-%02X-%02X-%02X-%02X-%02X\n",
167 ap_info->bssid[0],
168 ap_info->bssid[1],
169 ap_info->bssid[2],
170 ap_info->bssid[3],
171 ap_info->bssid[4],
172 ap_info->bssid[5]);
173 WIFI_DEBUG("JOIN rssi:%ddBm\n", ap_info->rssi);
174 WIFI_DEBUG("JOIN rate:%dMbps\n", ap_info->max_data_rate/1000);
175 WIFI_DEBUG("JOIN channel:%d\n", ap_info->channel);
176 WIFI_DEBUG("JOIN security:%08X\n\n", ap_info->security);
177 #endif /* WIFI_DEBUG_ON */
178 }
179 break;
180
181 case RW009_CMD_RSSI:
182 // TODO: client RSSI.
183 {
184 rw009_ap_info *ap_info = &resp->resp.ap_info;
185 wifi_device->ap_info.rssi = ap_info->rssi;
186 WIFI_DEBUG("current RSSI: %d\n", wifi_device->ap_info.rssi);
187 }
188 break;
189
190 case RW009_CMD_SOFTAP:
191 {
192 if( resp->result == 0 )
193 {
194 ;
195 wifi_device->active = 1;
196 eth_device_linkchange(&wifi_device->parent, RT_TRUE);
197 }
198 else
199 {
200 WIFI_DEBUG("RW009_CMD_EASY_JOIN result: %d\n", resp->result );
201 }
202
203 }
204 break;
205
206 default:
207 WIFI_DEBUG("resp_handler %d\n", resp->cmd);
208 break;
209 }
210
211
212 if(resp->cmd == wifi_device->last_cmd)
213 {
214 rt_mb_send(&wifi_device->rw009_cmd_mb, (rt_uint32_t)resp_return);
215 return;
216 }
217 else
218 {
219 rt_free(resp_return);
220 }
221 }
222
rw009_cmd(struct rw009_wifi * wifi_device,uint32_t cmd,void * args)223 static rt_err_t rw009_cmd(struct rw009_wifi *wifi_device, uint32_t cmd, void *args)
224 {
225 rt_err_t result = RT_EOK;
226 rt_int32_t timeout = RW009_CMD_TIMEOUT;
227
228 struct spi_data_packet *data_packet;
229 struct rw009_cmd *wifi_cmd = RT_NULL;
230 struct rw009_resp *resp = RT_NULL;
231
232 wifi_device->last_cmd = cmd;
233
234 data_packet = (struct spi_data_packet *)rt_mp_alloc(&wifi_device->spi_tx_mp, RT_WAITING_FOREVER);
235 wifi_cmd = (struct rw009_cmd *)data_packet->buffer;
236
237 wifi_cmd->cmd = cmd;
238 wifi_cmd->len = 0;
239
240 if( cmd == RW009_CMD_INIT )
241 {
242 wifi_cmd->len = sizeof(rw009_cmd_init);
243 }
244 else if( cmd == RW009_CMD_SCAN )
245 {
246 wifi_cmd->len = 0;
247 timeout += RT_TICK_PER_SECOND*10;
248
249 if(wifi_device->ap_scan)
250 {
251 rt_free(wifi_device->ap_scan);
252 wifi_device->ap_scan = RT_NULL;
253 wifi_device->ap_scan_count = 0;
254 }
255 }
256 else if( cmd == RW009_CMD_JOIN )
257 {
258 wifi_cmd->len = sizeof(rw009_cmd_join);
259 }
260 else if( cmd == RW009_CMD_EASY_JOIN )
261 {
262 wifi_cmd->len = sizeof(rw009_cmd_easy_join);
263 timeout += RT_TICK_PER_SECOND*5;
264 }
265 else if( cmd == RW009_CMD_RSSI )
266 {
267 wifi_cmd->len = sizeof(rw009_cmd_rssi);
268 }
269 else if( cmd == RW009_CMD_SOFTAP )
270 {
271 wifi_cmd->len = sizeof(rw009_cmd_softap);
272 }
273 else
274 {
275 WIFI_DEBUG("unkown RW009 CMD %d\n", cmd);
276 result = -RT_ENOSYS;
277 rt_mp_free(data_packet);
278 data_packet = RT_NULL;
279 }
280
281 if(data_packet == RT_NULL)
282 {
283 goto _exit;
284 }
285
286 if(wifi_cmd->len)
287 memcpy(&wifi_cmd->params, args, wifi_cmd->len);
288
289 data_packet->data_type = data_type_cmd;
290 data_packet->data_len = member_offset(struct rw009_cmd, params) + wifi_cmd->len;
291
292 rt_mb_send(&wifi_device->spi_tx_mb, (rt_uint32_t)data_packet);
293 rt_event_send(&spi_wifi_data_event, 1);
294
295 result = rt_mb_recv(&wifi_device->rw009_cmd_mb,
296 (rt_uint32_t *)&resp,
297 timeout);
298
299 if ( result != RT_EOK )
300 {
301 WIFI_DEBUG("CMD %d error, resultL %d\n", cmd, result );
302 }
303
304 if(resp != RT_NULL)
305 result = resp->result;
306
307 _exit:
308 wifi_device->last_cmd = 0;
309 if(resp) rt_free(resp);
310 return result;
311 }
312
spi_wifi_transfer(struct rw009_wifi * dev)313 static rt_err_t spi_wifi_transfer(struct rw009_wifi *dev)
314 {
315 struct pbuf *p = RT_NULL;
316 struct spi_cmd_request cmd;
317 struct spi_response resp;
318
319 rt_err_t result;
320 const struct spi_data_packet *data_packet = RT_NULL;
321
322 struct rw009_wifi *wifi_device = (struct rw009_wifi *)dev;
323 struct rt_spi_device *rt_spi_device = wifi_device->rt_spi_device;
324
325 spi_wifi_int_cmd(0);
326 while (spi_wifi_is_busy());
327 SPI_DEBUG("sequence start!\n");
328
329 memset(&cmd, 0, sizeof(struct spi_cmd_request));
330 cmd.magic1 = CMD_MAGIC1;
331 cmd.magic2 = CMD_MAGIC2;
332
333 cmd.flag |= CMD_FLAG_MRDY;
334
335 result = rt_mb_recv(&wifi_device->spi_tx_mb,
336 (rt_uint32_t *)&data_packet,
337 0);
338 if ((result == RT_EOK) && (data_packet != RT_NULL) && (data_packet->data_len > 0))
339 {
340 cmd.M2S_len = data_packet->data_len + member_offset(struct spi_data_packet, buffer);
341 //SPI_DEBUG("cmd.M2S_len = %d\n", cmd.M2S_len);
342 }
343
344 rt_spi_send(rt_spi_device, &cmd, sizeof(cmd));
345 while (spi_wifi_is_busy());
346
347 {
348 struct rt_spi_message message;
349 uint32_t max_data_len = 0;
350
351 /* setup message */
352 message.send_buf = RT_NULL;
353 message.recv_buf = &resp;
354 message.length = sizeof(resp);
355 message.cs_take = 1;
356 message.cs_release = 0;
357
358 rt_spi_take_bus(rt_spi_device);
359
360 /* transfer message */
361 rt_spi_device->bus->ops->xfer(rt_spi_device, &message);
362
363 if ((resp.magic1 != RESP_MAGIC1) || (resp.magic2 != RESP_MAGIC2))
364 {
365 SPI_DEBUG("bad resp magic, abort!\n");
366 goto _bad_resp_magic;
367 }
368
369 if (resp.flag & RESP_FLAG_SRDY)
370 {
371 SPI_DEBUG("RESP_FLAG_SRDY\n");
372 max_data_len = cmd.M2S_len;
373 }
374
375 if (resp.S2M_len)
376 {
377 SPI_DEBUG("resp.S2M_len: %d\n", resp.S2M_len);
378 if (resp.S2M_len > MAX_SPI_PACKET_SIZE)
379 {
380 SPI_DEBUG("resp.S2M_len %d > %d(MAX_SPI_PACKET_SIZE), drop!\n", resp.S2M_len, MAX_SPI_PACKET_SIZE);
381 resp.S2M_len = 0;//drop
382 }
383
384 if (resp.S2M_len > max_data_len)
385 max_data_len = resp.S2M_len;
386 }
387
388 if (max_data_len == 0)
389 {
390 SPI_DEBUG("no rx or tx data!\n");
391 }
392
393 //SPI_DEBUG("max_data_len = %d\n", max_data_len);
394
395 _bad_resp_magic:
396 /* setup message */
397 message.send_buf = data_packet;//&tx_buffer;
398 message.recv_buf = wifi_device->spi_hw_rx_buffer;//&rx_buffer;
399 message.length = max_data_len;
400 message.cs_take = 0;
401 message.cs_release = 1;
402
403 /* transfer message */
404 rt_spi_device->bus->ops->xfer(rt_spi_device, &message);
405
406 rt_spi_release_bus(rt_spi_device);
407
408 if (cmd.M2S_len && (resp.flag & RESP_FLAG_SRDY))
409 {
410 rt_mp_free((void *)data_packet);
411 }
412
413 if ((resp.S2M_len) && (resp.S2M_len <= MAX_SPI_PACKET_SIZE))
414 {
415 data_packet = (struct spi_data_packet *)wifi_device->spi_hw_rx_buffer;
416 if (data_packet->data_type == data_type_eth_data)
417 {
418
419 if (wifi_device->active)
420 {
421 p = pbuf_alloc(PBUF_LINK, data_packet->data_len, PBUF_RAM);
422 pbuf_take(p, (rt_uint8_t *)data_packet->buffer, data_packet->data_len);
423
424 rt_mb_send(&wifi_device->eth_rx_mb, (rt_uint32_t)p);
425 eth_device_ready((struct eth_device *)dev);
426 }
427 else
428 {
429 SPI_DEBUG("!active, RX drop.\n");
430 }
431 }
432 else if (data_packet->data_type == data_type_resp)
433 {
434 SPI_DEBUG("data_type_resp\n");
435 resp_handler(dev, (struct rw009_resp *)data_packet->buffer);
436 }
437 else
438 {
439 SPI_DEBUG("data_type: %d, %dbyte\n",
440 data_packet->data_type,
441 data_packet->data_len);
442 }
443 }
444 }
445 spi_wifi_int_cmd(1);
446
447 SPI_DEBUG("sequence finish!\n\n");
448
449 if ((cmd.M2S_len == 0) && (resp.S2M_len == 0))
450 {
451 return -RT_ERROR;
452 }
453
454 return RT_EOK;
455 }
456
457 #if defined(ETH_RX_DUMP) || defined(ETH_TX_DUMP)
packet_dump(const char * msg,const struct pbuf * p)458 static void packet_dump(const char *msg, const struct pbuf *p)
459 {
460 const struct pbuf* q;
461 rt_uint32_t i,j;
462 rt_uint8_t *ptr = p->payload;
463
464 rt_kprintf("%s %d byte\n", msg, p->tot_len);
465
466 i=0;
467 for(q=p; q != RT_NULL; q= q->next)
468 {
469 ptr = q->payload;
470
471 for(j=0; j<q->len; j++)
472 {
473 if( (i%8) == 0 )
474 {
475 rt_kprintf(" ");
476 }
477 if( (i%16) == 0 )
478 {
479 rt_kprintf("\r\n");
480 }
481 rt_kprintf("%02x ",*ptr);
482
483 i++;
484 ptr++;
485 }
486 }
487 rt_kprintf("\n\n");
488 }
489 #endif /* dump */
490
491 /********************************* RT-Thread Ethernet interface begin **************************************/
rw009_wifi_init(rt_device_t dev)492 static rt_err_t rw009_wifi_init(rt_device_t dev)
493 {
494 return RT_EOK;
495 }
496
rw009_wifi_open(rt_device_t dev,rt_uint16_t oflag)497 static rt_err_t rw009_wifi_open(rt_device_t dev, rt_uint16_t oflag)
498 {
499 return RT_EOK;
500 }
501
rw009_wifi_close(rt_device_t dev)502 static rt_err_t rw009_wifi_close(rt_device_t dev)
503 {
504 return RT_EOK;
505 }
506
rw009_wifi_read(rt_device_t dev,rt_off_t pos,void * buffer,rt_size_t size)507 static rt_size_t rw009_wifi_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
508 {
509 rt_set_errno(-RT_ENOSYS);
510 return 0;
511 }
512
rw009_wifi_write(rt_device_t dev,rt_off_t pos,const void * buffer,rt_size_t size)513 static rt_size_t rw009_wifi_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
514 {
515 rt_set_errno(-RT_ENOSYS);
516 return 0;
517 }
518
rw009_wifi_control(rt_device_t dev,int cmd,void * args)519 static rt_err_t rw009_wifi_control(rt_device_t dev, int cmd, void *args)
520 {
521 struct rw009_wifi *wifi_device = (struct rw009_wifi *)dev;
522 rt_err_t result = RT_EOK;
523
524 if (cmd == NIOCTL_GADDR)
525 {
526 memcpy(args, wifi_device->dev_addr, 6);
527 }
528 else
529 {
530 result = rw009_cmd(wifi_device, cmd, args);
531 }
532
533 return result;
534 }
535
536 /* transmit packet. */
rw009_wifi_tx(rt_device_t dev,struct pbuf * p)537 rt_err_t rw009_wifi_tx(rt_device_t dev, struct pbuf *p)
538 {
539 rt_err_t result = RT_EOK;
540 struct spi_data_packet *data_packet;
541 struct rw009_wifi *wifi_device = (struct rw009_wifi *)dev;
542
543 if (!wifi_device->active)
544 {
545 WIFI_DEBUG("!active, TX drop!\n");
546 return RT_EOK;
547 }
548
549 /* get free tx buffer */
550 data_packet = (struct spi_data_packet *)rt_mp_alloc(&wifi_device->spi_tx_mp, RT_WAITING_FOREVER);
551 if (data_packet != RT_NULL)
552 {
553 data_packet->data_type = data_type_eth_data;
554 data_packet->data_len = p->tot_len;
555
556 pbuf_copy_partial(p, data_packet->buffer, data_packet->data_len, 0);
557
558 rt_mb_send(&wifi_device->spi_tx_mb, (rt_uint32_t)data_packet);
559 rt_event_send(&spi_wifi_data_event, 1);
560 }
561 else
562 return -RT_ERROR;
563
564 #ifdef ETH_TX_DUMP
565 packet_dump("TX dump", p);
566 #endif /* ETH_TX_DUMP */
567
568 /* Return SUCCESS */
569 return result;
570 }
571
572 /* reception packet. */
rw009_wifi_rx(rt_device_t dev)573 struct pbuf *rw009_wifi_rx(rt_device_t dev)
574 {
575 struct pbuf *p = RT_NULL;
576 struct rw009_wifi *wifi_device = (struct rw009_wifi *)dev;
577
578 if (rt_mb_recv(&wifi_device->eth_rx_mb, (rt_uint32_t *)&p, 0) != RT_EOK)
579 {
580 return RT_NULL;
581 }
582
583 #ifdef ETH_RX_DUMP
584 if(p)
585 packet_dump("RX dump", p);
586 #endif /* ETH_RX_DUMP */
587
588 return p;
589 }
590 /********************************* RT-Thread Ethernet interface end **************************************/
591
spi_wifi_data_thread_entry(void * parameter)592 static void spi_wifi_data_thread_entry(void *parameter)
593 {
594 rt_uint32_t e;
595 rt_err_t result;
596
597 while (1)
598 {
599 /* receive first event */
600 if (rt_event_recv(&spi_wifi_data_event,
601 1,
602 RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR,
603 RT_WAITING_FOREVER,
604 &e) != RT_EOK)
605 {
606 continue;
607 }
608
609 result = spi_wifi_transfer(&rw009_wifi_device);
610
611 if (result == RT_EOK)
612 {
613 rt_event_send(&spi_wifi_data_event, 1);
614 }
615 }
616 }
617
618 #ifdef RT_USING_DEVICE_OPS
619 const static struct rt_device_ops rw009_ops =
620 {
621 rw009_wifi_init,
622 rw009_wifi_open,
623 rw009_wifi_close,
624 rw009_wifi_read,
625 rw009_wifi_write,
626 rw009_wifi_control
627 };
628 #endif
629
rt_hw_wifi_init(const char * spi_device_name,wifi_mode_t mode)630 rt_err_t rt_hw_wifi_init(const char *spi_device_name, wifi_mode_t mode)
631 {
632 /* align and struct size check. */
633 RT_ASSERT( (SPI_MAX_DATA_LEN & 0x03) == 0);
634 RT_ASSERT( sizeof(struct rw009_resp) <= SPI_MAX_DATA_LEN);
635
636 memset(&rw009_wifi_device, 0, sizeof(struct rw009_wifi));
637
638 rw009_wifi_device.rt_spi_device = (struct rt_spi_device *)rt_device_find(spi_device_name);
639
640 if (rw009_wifi_device.rt_spi_device == RT_NULL)
641 {
642 SPI_DEBUG("spi device %s not found!\r\n", spi_device_name);
643 return -RT_ENOSYS;
644 }
645
646 /* config spi */
647 {
648 struct rt_spi_configuration cfg;
649 cfg.data_width = 8;
650 cfg.mode = RT_SPI_MODE_0 | RT_SPI_MSB; /* SPI Compatible: Mode 0. */
651 cfg.max_hz = 15 * 1000000; /* 10M */
652 rt_spi_configure(rw009_wifi_device.rt_spi_device, &cfg);
653 }
654
655 #ifdef RT_USING_DEVICE_OPS
656 rw009_wifi_device.parent.parent.ops = &rw009_ops;
657 #else
658 rw009_wifi_device.parent.parent.init = rw009_wifi_init;
659 rw009_wifi_device.parent.parent.open = rw009_wifi_open;
660 rw009_wifi_device.parent.parent.close = rw009_wifi_close;
661 rw009_wifi_device.parent.parent.read = rw009_wifi_read;
662 rw009_wifi_device.parent.parent.write = rw009_wifi_write;
663 rw009_wifi_device.parent.parent.control = rw009_wifi_control;
664 #endif
665 rw009_wifi_device.parent.parent.user_data = RT_NULL;
666
667 rw009_wifi_device.parent.eth_rx = rw009_wifi_rx;
668 rw009_wifi_device.parent.eth_tx = rw009_wifi_tx;
669
670 rt_mp_init(&rw009_wifi_device.spi_tx_mp,
671 "spi_tx",
672 &rw009_wifi_device.spi_tx_mempool[0],
673 sizeof(rw009_wifi_device.spi_tx_mempool),
674 sizeof(struct spi_data_packet));
675
676 rt_mp_init(&rw009_wifi_device.spi_rx_mp,
677 "spi_rx",
678 &rw009_wifi_device.spi_rx_mempool[0],
679 sizeof(rw009_wifi_device.spi_rx_mempool),
680 sizeof(struct spi_data_packet));
681
682 rt_mb_init(&rw009_wifi_device.spi_tx_mb,
683 "spi_tx",
684 &rw009_wifi_device.spi_tx_mb_pool[0],
685 SPI_TX_POOL_SIZE,
686 RT_IPC_FLAG_PRIO);
687
688 rt_mb_init(&rw009_wifi_device.eth_rx_mb,
689 "eth_rx",
690 &rw009_wifi_device.eth_rx_mb_pool[0],
691 SPI_TX_POOL_SIZE,
692 RT_IPC_FLAG_PRIO);
693
694 rt_mb_init(&rw009_wifi_device.rw009_cmd_mb,
695 "wifi_cmd",
696 &rw009_wifi_device.rw009_cmd_mb_pool[0],
697 sizeof(rw009_wifi_device.rw009_cmd_mb_pool) / 4,
698 RT_IPC_FLAG_PRIO);
699 rt_event_init(&spi_wifi_data_event, "wifi", RT_IPC_FLAG_FIFO);
700
701 spi_wifi_hw_init();
702
703 {
704 rt_thread_t tid;
705
706
707 tid = rt_thread_create("wifi",
708 spi_wifi_data_thread_entry,
709 RT_NULL,
710 2048,
711 RT_THREAD_PRIORITY_MAX - 2,
712 20);
713
714 if (tid != RT_NULL)
715 rt_thread_startup(tid);
716 }
717
718 /* init: get mac address */
719 {
720 rw009_cmd_init init;
721 init.mode = mode;
722 WIFI_DEBUG("wifi_control RW009_CMD_INIT\n");
723 rw009_wifi_control((rt_device_t)&rw009_wifi_device,
724 RW009_CMD_INIT,
725 (void *)&init); // 0: firmware, 1: STA, 2:AP
726
727 }
728
729 /* register eth device */
730 eth_device_init(&(rw009_wifi_device.parent), "w0");
731 eth_device_linkchange(&rw009_wifi_device.parent, RT_FALSE);
732
733 return RT_EOK;
734 }
735
spi_wifi_isr(int vector)736 void spi_wifi_isr(int vector)
737 {
738 /* enter interrupt */
739 rt_interrupt_enter();
740
741 SPI_DEBUG("spi_wifi_isr\n");
742 rt_event_send(&spi_wifi_data_event, 1);
743
744 /* leave interrupt */
745 rt_interrupt_leave();
746 }
747
748 /********************************* RW009 tools **************************************/
rw009_join(const char * SSID,const char * passwd)749 rt_err_t rw009_join(const char * SSID, const char * passwd)
750 {
751 rt_err_t result;
752 rt_device_t wifi_device;
753 rw009_cmd_easy_join easy_join;
754
755 wifi_device = rt_device_find("w0");
756 if(wifi_device == RT_NULL)
757 return -RT_ENOSYS;
758
759 strncpy( easy_join.ssid, SSID, sizeof(easy_join.ssid) );
760 strncpy( easy_join.passwd, passwd, sizeof(easy_join.passwd) );
761
762 result = rt_device_control(wifi_device,
763 RW009_CMD_EASY_JOIN,
764 (void *)&easy_join);
765
766 return result;
767 }
768
rw009_softap(const char * SSID,const char * passwd,uint32_t security,uint32_t channel)769 rt_err_t rw009_softap(const char * SSID, const char * passwd,uint32_t security,uint32_t channel)
770 {
771 rt_err_t result;
772 rt_device_t wifi_device;
773 rw009_cmd_softap softap;
774
775 wifi_device = rt_device_find("w0");
776 if(wifi_device == RT_NULL)
777 return -RT_ENOSYS;
778
779 strncpy( softap.ssid, SSID, sizeof(softap.ssid) );
780 strncpy( softap.passwd, passwd, sizeof(softap.passwd) );
781
782 softap.security = security;
783 softap.channel = channel;
784 result = rt_device_control(wifi_device,
785 RW009_CMD_SOFTAP,
786 (void *)&softap);
787
788 return result;
789 }
790
rw009_rssi(void)791 int32_t rw009_rssi(void)
792 {
793 rt_err_t result;
794 struct rw009_wifi * wifi_device;
795
796 wifi_device = (struct rw009_wifi *)rt_device_find("w0");
797
798 if(wifi_device == RT_NULL)
799 return 0;
800
801 if(wifi_device->active == 0)
802 return 0;
803
804 // SCAN
805 result = rt_device_control((rt_device_t)wifi_device,
806 RW009_CMD_RSSI,
807 RT_NULL);
808
809 if(result == RT_EOK)
810 {
811 return wifi_device->ap_info.rssi;
812 }
813
814 return 0;
815 }
816
817 #ifdef RT_USING_FINSH
818 #include <finsh.h>
819
rw009_scan(void)820 static rt_err_t rw009_scan(void)
821 {
822 rt_err_t result;
823 struct rw009_wifi * wifi_device;
824
825 wifi_device = (struct rw009_wifi *)rt_device_find("w0");
826
827 rt_kprintf("\nCMD RW009_CMD_SCAN \n");
828 result = rt_device_control((rt_device_t)wifi_device,
829 RW009_CMD_SCAN,
830 RT_NULL);
831
832 rt_kprintf("CMD RW009_CMD_SCAN result:%d\n", result);
833
834 if(result == RT_EOK)
835 {
836 uint32_t i;
837 rw009_ap_info *ap_info;
838
839 for(i=0; i<wifi_device->ap_scan_count; i++)
840 {
841 ap_info = &wifi_device->ap_scan[i];
842 rt_kprintf("AP #%02d SSID: %-32.32s\n", i, ap_info->ssid );
843 }
844 }
845
846 return result;
847 }
848 FINSH_FUNCTION_EXPORT(rw009_scan, SACN and list AP.);
849 FINSH_FUNCTION_EXPORT(rw009_join, RW009 join to AP.);
850 FINSH_FUNCTION_EXPORT(rw009_rssi, get RW009 current AP rssi.);
851
852 #endif // RT_USING_FINSH
853