spi_wifi_rw009.c 24 KB

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