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 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 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 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) 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 **************************************/ 492 static rt_err_t rw009_wifi_init(rt_device_t dev) 493 { 494 return RT_EOK; 495 } 496 497 static rt_err_t rw009_wifi_open(rt_device_t dev, rt_uint16_t oflag) 498 { 499 return RT_EOK; 500 } 501 502 static rt_err_t rw009_wifi_close(rt_device_t dev) 503 { 504 return RT_EOK; 505 } 506 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 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 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. */ 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. */ 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 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 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 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 **************************************/ 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 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 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 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