spi_wifi_rw009.c 24 KB

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