spi_wifi_rw009.c 23 KB

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