Selaa lähdekoodia

update RW009 wifi driver.

aozima 10 vuotta sitten
vanhempi
commit
3c99a5bf8d
2 muutettua tiedostoa jossa 464 lisäystä ja 218 poistoa
  1. 380 182
      components/drivers/spi/spi_wifi_rw009.c
  2. 84 36
      components/drivers/spi/spi_wifi_rw009.h

+ 380 - 182
components/drivers/spi/spi_wifi_rw009.c

@@ -20,6 +20,7 @@
  * Change Logs:
  * Date           Author       Notes
  * 2014-07-31     aozima       the first version
+ * 2014-09-18     aozima       update command & response.
  */
 
 #include <rtthread.h>
@@ -30,24 +31,33 @@
 #include <lwip/icmp.h>
 #include "lwipopts.h"
 
-#include "spi_wifi_rw009.h"
-
-#define SSID_NAME      "AP_SSID"
-#define SSID_PASSWORD  "AP_passwd"
-
-// #define WIFI_DEBUG_ON
+#define WIFI_DEBUG_ON
 // #define ETH_RX_DUMP
 // #define ETH_TX_DUMP
 
 #ifdef WIFI_DEBUG_ON
-#define WIFI_DEBUG         rt_kprintf("[WIFI] ");rt_kprintf
+#define WIFI_DEBUG         rt_kprintf("[RW009] ");rt_kprintf
+//#define SPI_DEBUG         rt_kprintf("[SPI] ");rt_kprintf
+#define SPI_DEBUG(...)
 #else
 #define WIFI_DEBUG(...)
+#define SPI_DEBUG(...)
 #endif /* #ifdef WIFI_DEBUG_ON */
 
-#define MAX_BUFFER_SIZE     (sizeof(struct response) + MAX_DATA_LEN)
+/********************************* RW009 **************************************/
+#include "spi_wifi_rw009.h"
+
+/* tools */
+#define node_entry(node, type, member) \
+    ((type *)((char *)(node) - (unsigned long)(&((type *)0)->member)))
+#define member_offset(type, member) \
+    ((unsigned long)(&((type *)0)->member))
+
+#define MAX_SPI_PACKET_SIZE     (member_offset(struct spi_data_packet, buffer) + SPI_MAX_DATA_LEN)
+#define MAX_SPI_BUFFER_SIZE     (sizeof(struct spi_response) + MAX_SPI_PACKET_SIZE)
 #define MAX_ADDR_LEN 6
-struct spi_wifi_eth
+
+struct rw009_wifi
 {
     /* inherit from ethernet device */
     struct eth_device parent;
@@ -67,8 +77,9 @@ struct spi_wifi_eth
     int spi_tx_mb_pool[SPI_TX_POOL_SIZE + 1];
     int eth_rx_mb_pool[SPI_RX_POOL_SIZE + 1];
 
-    int spi_wifi_cmd_mb_pool[3];
-    struct rt_mailbox spi_wifi_cmd_mb;
+    int rw009_cmd_mb_pool[3];
+    struct rt_mailbox rw009_cmd_mb;
+    uint32_t last_cmd;
 
     ALIGN(4)
     rt_uint8_t spi_tx_mempool[(sizeof(struct spi_data_packet) + 4) * SPI_TX_POOL_SIZE];
@@ -76,32 +87,112 @@ struct spi_wifi_eth
     rt_uint8_t spi_rx_mempool[(sizeof(struct spi_data_packet) + 4) * SPI_RX_POOL_SIZE];
 
     ALIGN(4)
-    uint8_t spi_hw_rx_buffer[MAX_BUFFER_SIZE];
+    uint8_t spi_hw_rx_buffer[MAX_SPI_BUFFER_SIZE];
+
+    /* status for RW009 */
+    rw009_ap_info ap_info;  /* AP info for conn. */
+    rw009_ap_info *ap_scan; /* AP list for SCAN. */
+    uint32_t ap_scan_count;
 };
-static struct spi_wifi_eth spi_wifi_device;
+static struct rw009_wifi rw009_wifi_device;
 static struct rt_event spi_wifi_data_event;
 
-static void resp_handler(struct spi_wifi_eth *wifi_device, struct spi_wifi_resp *resp)
+static void resp_handler(struct rw009_wifi *wifi_device, struct rw009_resp *resp)
 {
-    struct spi_wifi_resp *resp_return;
+    struct rw009_resp *resp_return = RT_NULL;
 
     switch (resp->cmd)
     {
-    case SPI_WIFI_CMD_INIT:
-        WIFI_DEBUG("resp_handler SPI_WIFI_CMD_INIT\n");
-        resp_return = (struct spi_wifi_resp *)rt_malloc(sizeof(struct spi_wifi_resp)); //TODO:
-        memcpy(resp_return, resp, 10);
-        rt_mb_send(&wifi_device->spi_wifi_cmd_mb, (rt_uint32_t)resp_return);
+    case RW009_CMD_INIT:
+        WIFI_DEBUG("resp_handler RW009_CMD_INIT\n");
+        resp_return = (struct rw009_resp *)rt_malloc(member_offset(struct rw009_resp, resp) + sizeof(rw009_resp_init)); //TODO:
+        if(resp_return == RT_NULL) break;
+        memcpy(resp_return, resp, member_offset(struct rw009_resp, resp) + sizeof(rw009_resp_init));
+
+        WIFI_DEBUG("sn:%-*.*s\n", sizeof(resp->resp.init.sn), sizeof(resp->resp.init.sn), resp->resp.init.sn);
+        WIFI_DEBUG("version:%-*.*s\n", sizeof(resp->resp.init.version), sizeof(resp->resp.init.version), resp->resp.init.version);
+
+        rt_memcpy(wifi_device->dev_addr, resp->resp.init.mac, 6);
         break;
 
-    case SPI_WIFI_CMD_SCAN:
-        WIFI_DEBUG("resp_handler SPI_WIFI_CMD_SCAN\n");
+    case RW009_CMD_SCAN:
+        if( resp->len == sizeof(rw009_ap_info) )
+        {
+            rw009_ap_info *ap_scan = rt_realloc(wifi_device->ap_scan, sizeof(rw009_ap_info) * (wifi_device->ap_scan_count + 1) );
+            if(ap_scan != RT_NULL)
+            {
+                memcpy( &ap_scan[wifi_device->ap_scan_count], &resp->resp.ap_info, sizeof(rw009_ap_info) );
+
+                //dump
+                if(1)
+                {
+                    rw009_ap_info *ap_info = &resp->resp.ap_info;
+                    WIFI_DEBUG("SCAN SSID:%-32.32s\n", ap_info->ssid);
+                    WIFI_DEBUG("SCAN BSSID:%02X-%02X-%02X-%02X-%02X-%02X\n",
+                               ap_info->bssid[0],
+                               ap_info->bssid[1],
+                               ap_info->bssid[2],
+                               ap_info->bssid[3],
+                               ap_info->bssid[4],
+                               ap_info->bssid[5]);
+                    WIFI_DEBUG("SCAN rssi:%ddBm\n", ap_info->rssi);
+                    WIFI_DEBUG("SCAN rate:%dMbps\n", ap_info->max_data_rate/1000);
+                    WIFI_DEBUG("SCAN channel:%d\n", ap_info->channel);
+                    WIFI_DEBUG("SCAN security:%08X\n\n", ap_info->security);
+                }
+
+                wifi_device->ap_scan_count++;
+                wifi_device->ap_scan = ap_scan;
+            }
+
+            return; /* wait for next ap */
+        }
         break;
 
-    case SPI_WIFI_CMD_JOIN:
-        WIFI_DEBUG("resp_handler SPI_WIFI_CMD_JOIN\n");
-        wifi_device->active = 1;
-        eth_device_linkchange(&wifi_device->parent, RT_TRUE);
+    case RW009_CMD_JOIN:
+    case RW009_CMD_EASY_JOIN:
+        WIFI_DEBUG("resp_handler RW009_CMD_EASY_JOIN\n");
+        resp_return = (struct rw009_resp *)rt_malloc(member_offset(struct rw009_resp, resp) + sizeof(rw009_resp_join)); //TODO:
+        if(resp_return == RT_NULL) break;
+        memcpy(resp_return, resp, member_offset(struct rw009_resp, resp) + sizeof(rw009_resp_join));
+
+        if( resp->result == 0 )
+        {
+            memcpy(&wifi_device->ap_info, &resp_return->resp.ap_info, sizeof(rw009_resp_join));
+            wifi_device->active = 1;
+            eth_device_linkchange(&wifi_device->parent, RT_TRUE);
+        }
+        else
+        {
+            WIFI_DEBUG("RW009_CMD_EASY_JOIN result: %d\n", resp->result );
+        }
+
+        //dupm
+        if(1)
+        {
+            rw009_ap_info *ap_info = &resp->resp.ap_info;
+            WIFI_DEBUG("JOIN SSID:%-32.32s\n", ap_info->ssid);
+            WIFI_DEBUG("JOIN BSSID:%02X-%02X-%02X-%02X-%02X-%02X\n",
+                       ap_info->bssid[0],
+                       ap_info->bssid[1],
+                       ap_info->bssid[2],
+                       ap_info->bssid[3],
+                       ap_info->bssid[4],
+                       ap_info->bssid[5]);
+            WIFI_DEBUG("JOIN rssi:%ddBm\n", ap_info->rssi);
+            WIFI_DEBUG("JOIN rate:%dMbps\n", ap_info->max_data_rate/1000);
+            WIFI_DEBUG("JOIN channel:%d\n", ap_info->channel);
+            WIFI_DEBUG("JOIN security:%08X\n\n", ap_info->security);
+        }
+        break;
+
+    case RW009_CMD_RSSI:
+        // TODO: client RSSI.
+        {
+            rw009_ap_info *ap_info = &resp->resp.ap_info;
+            wifi_device->ap_info.rssi = ap_info->rssi;
+            WIFI_DEBUG("current RSSI: %d\n", wifi_device->ap_info.rssi);
+        }
         break;
 
     default:
@@ -109,25 +200,121 @@ static void resp_handler(struct spi_wifi_eth *wifi_device, struct spi_wifi_resp
         break;
     }
 
+
+    if(resp->cmd == wifi_device->last_cmd)
+    {
+        rt_mb_send(&wifi_device->rw009_cmd_mb, (rt_uint32_t)resp_return);
+        return;
+    }
+    else
+    {
+        rt_free(resp_return);
+    }
+}
+
+static rt_err_t rw009_cmd(struct rw009_wifi *wifi_device, uint32_t cmd, void *args)
+{
+    rt_err_t result = RT_EOK;
+    rt_int32_t timeout = RW009_CMD_TIMEOUT;
+
+    struct spi_data_packet *data_packet;
+    struct rw009_cmd *wifi_cmd = RT_NULL;
+    struct rw009_resp *resp = RT_NULL;
+
+    wifi_device->last_cmd = cmd;
+
+    data_packet = (struct spi_data_packet *)rt_mp_alloc(&wifi_device->spi_tx_mp, RT_WAITING_FOREVER);
+    wifi_cmd = (struct rw009_cmd *)data_packet->buffer;
+
+    wifi_cmd->cmd = cmd;
+    wifi_cmd->len = 0;
+
+    if( cmd == RW009_CMD_INIT )
+    {
+        wifi_cmd->len = sizeof(rw009_cmd_init);
+    }
+    else if( cmd == RW009_CMD_SCAN )
+    {
+        wifi_cmd->len = 0;
+        timeout += RT_TICK_PER_SECOND*10;
+
+        if(wifi_device->ap_scan)
+        {
+            rt_free(wifi_device->ap_scan);
+            wifi_device->ap_scan = RT_NULL;
+            wifi_device->ap_scan_count = 0;
+        }
+    }
+    else if( cmd == RW009_CMD_JOIN )
+    {
+        wifi_cmd->len = sizeof(rw009_cmd_join);
+    }
+    else if( cmd == RW009_CMD_EASY_JOIN )
+    {
+        wifi_cmd->len = sizeof(rw009_cmd_easy_join);
+        timeout += RT_TICK_PER_SECOND*5;
+    }
+    else if( cmd == RW009_CMD_RSSI )
+    {
+        wifi_cmd->len = sizeof(rw009_cmd_rssi);
+    }
+    else
+    {
+        WIFI_DEBUG("unkown RW009 CMD %d\n", cmd);
+        result = -RT_ENOSYS;
+        rt_mp_free(data_packet);
+        data_packet = RT_NULL;
+    }
+
+    if(data_packet == RT_NULL)
+    {
+        goto _exit;
+    }
+
+    if(wifi_cmd->len)
+        memcpy(&wifi_cmd->params, args, wifi_cmd->len);
+
+    data_packet->data_type = data_type_cmd;
+    data_packet->data_len = member_offset(struct rw009_cmd, params) + wifi_cmd->len;
+
+    rt_mb_send(&wifi_device->spi_tx_mb, (rt_uint32_t)data_packet);
+    rt_event_send(&spi_wifi_data_event, 1);
+
+    result = rt_mb_recv(&wifi_device->rw009_cmd_mb,
+                        (rt_uint32_t *)&resp,
+                        timeout);
+
+    if ( result != RT_EOK )
+    {
+        WIFI_DEBUG("CMD %d error, resultL %d\n", cmd, result );
+    }
+
+    if(resp != RT_NULL)
+        result = resp->result;
+
+_exit:
+    wifi_device->last_cmd = 0;
+    if(resp) rt_free(resp);
+    return result;
 }
 
-static rt_err_t spi_wifi_transfer(struct spi_wifi_eth *dev)
+static rt_err_t spi_wifi_transfer(struct rw009_wifi *dev)
 {
     struct pbuf *p = RT_NULL;
-    struct cmd_request cmd;
-    struct response resp;
+    struct spi_cmd_request cmd;
+    struct spi_response resp;
 
     rt_err_t result;
     const struct spi_data_packet *data_packet = RT_NULL;
 
-    struct spi_wifi_eth *wifi_device = (struct spi_wifi_eth *)dev;
+    struct rw009_wifi *wifi_device = (struct rw009_wifi *)dev;
     struct rt_spi_device *rt_spi_device = wifi_device->rt_spi_device;
 
     spi_wifi_int_cmd(0);
     while (spi_wifi_is_busy());
-    WIFI_DEBUG("sequence start!\n");
+    SPI_DEBUG("sequence start!\n");
 
-    memset(&cmd, 0, sizeof(struct cmd_request));
+    memset(&cmd, 0, sizeof(struct spi_cmd_request));
     cmd.magic1 = CMD_MAGIC1;
     cmd.magic2 = CMD_MAGIC2;
 
@@ -139,7 +326,7 @@ static rt_err_t spi_wifi_transfer(struct spi_wifi_eth *dev)
     if ((result == RT_EOK) && (data_packet != RT_NULL) && (data_packet->data_len > 0))
     {
         cmd.M2S_len = data_packet->data_len + member_offset(struct spi_data_packet, buffer);
-        //WIFI_DEBUG("cmd.M2S_len = %d\n", cmd.M2S_len);
+        //SPI_DEBUG("cmd.M2S_len = %d\n", cmd.M2S_len);
     }
 
     rt_spi_send(rt_spi_device, &cmd, sizeof(cmd));
@@ -163,22 +350,22 @@ static rt_err_t spi_wifi_transfer(struct spi_wifi_eth *dev)
 
         if ((resp.magic1 != RESP_MAGIC1) || (resp.magic2 != RESP_MAGIC2))
         {
-            WIFI_DEBUG("bad resp magic, abort!\n");
+            SPI_DEBUG("bad resp magic, abort!\n");
             goto _bad_resp_magic;
         }
 
         if (resp.flag & RESP_FLAG_SRDY)
         {
-            WIFI_DEBUG("RESP_FLAG_SRDY\n");
+            SPI_DEBUG("RESP_FLAG_SRDY\n");
             max_data_len = cmd.M2S_len;
         }
 
         if (resp.S2M_len)
         {
-            WIFI_DEBUG("resp.S2M_len: %d\n", resp.S2M_len);
+            SPI_DEBUG("resp.S2M_len: %d\n", resp.S2M_len);
             if (resp.S2M_len > MAX_SPI_PACKET_SIZE)
             {
-                WIFI_DEBUG("resp.S2M_len %d > %d(MAX_SPI_PACKET_SIZE), drop!\n", resp.S2M_len, MAX_SPI_PACKET_SIZE);
+                SPI_DEBUG("resp.S2M_len %d > %d(MAX_SPI_PACKET_SIZE), drop!\n", resp.S2M_len, MAX_SPI_PACKET_SIZE);
                 resp.S2M_len = 0;//drop
             }
 
@@ -188,10 +375,10 @@ static rt_err_t spi_wifi_transfer(struct spi_wifi_eth *dev)
 
         if (max_data_len == 0)
         {
-            WIFI_DEBUG("no rx or tx data!\n");
+            SPI_DEBUG("no rx or tx data!\n");
         }
 
-        //WIFI_DEBUG("max_data_len = %d\n", max_data_len);
+        //SPI_DEBUG("max_data_len = %d\n", max_data_len);
 
 _bad_resp_magic:
         /* setup message */
@@ -227,25 +414,25 @@ _bad_resp_magic:
                 }
                 else
                 {
-                    WIFI_DEBUG("!active, RX drop.\n");
+                    SPI_DEBUG("!active, RX drop.\n");
                 }
             }
             else if (data_packet->data_type == data_type_resp)
             {
-                WIFI_DEBUG("data_type_resp\n");
-                resp_handler(dev, (struct spi_wifi_resp *)data_packet->buffer);
+                SPI_DEBUG("data_type_resp\n");
+                resp_handler(dev, (struct rw009_resp *)data_packet->buffer);
             }
             else
             {
-                WIFI_DEBUG("data_type: %d, %dbyte\n",
-                           data_packet->data_type,
-                           data_packet->data_len);
+                SPI_DEBUG("data_type: %d, %dbyte\n",
+                          data_packet->data_type,
+                          data_packet->data_len);
             }
         }
     }
     spi_wifi_int_cmd(1);
 
-    WIFI_DEBUG("sequence finish!\n\n");
+    SPI_DEBUG("sequence finish!\n\n");
 
     if ((cmd.M2S_len == 0) && (resp.S2M_len == 0))
     {
@@ -289,127 +476,57 @@ static void packet_dump(const char *msg, const struct pbuf *p)
 }
 #endif /* dump */
 
-/* initialize the interface */
-static rt_err_t spi_wifi_eth_init(rt_device_t dev)
+/********************************* RT-Thread Ethernet interface begin **************************************/
+static rt_err_t rw009_wifi_init(rt_device_t dev)
 {
     return RT_EOK;
 }
 
-static rt_err_t spi_wifi_eth_open(rt_device_t dev, rt_uint16_t oflag)
+static rt_err_t rw009_wifi_open(rt_device_t dev, rt_uint16_t oflag)
 {
     return RT_EOK;
 }
 
-static rt_err_t spi_wifi_eth_close(rt_device_t dev)
+static rt_err_t rw009_wifi_close(rt_device_t dev)
 {
     return RT_EOK;
 }
 
-static rt_size_t spi_wifi_eth_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
+static rt_size_t rw009_wifi_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
 {
     rt_set_errno(-RT_ENOSYS);
     return 0;
 }
 
-static rt_size_t spi_wifi_eth_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
+static rt_size_t rw009_wifi_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
 {
     rt_set_errno(-RT_ENOSYS);
     return 0;
 }
 
-
-static rt_err_t spi_wifi_eth_control(rt_device_t dev, rt_uint8_t cmd, void *args)
+static rt_err_t rw009_wifi_control(rt_device_t dev, rt_uint8_t cmd, void *args)
 {
-    struct spi_wifi_eth *wifi_device = (struct spi_wifi_eth *)dev;
-    struct spi_data_packet *data_packet;
-    struct spi_wifi_cmd *wifi_cmd;
-    struct spi_wifi_resp *resp;
+    struct rw009_wifi *wifi_device = (struct rw009_wifi *)dev;
+    rt_err_t result = RT_EOK;
 
-    switch (cmd)
+    if (cmd == NIOCTL_GADDR)
     {
-    case NIOCTL_GADDR:
         memcpy(args, wifi_device->dev_addr, 6);
-        break;
-
-    case SPI_WIFI_CMD_INIT:
-        /* get mac address */
-        if (args)
-        {
-            rt_err_t result;
-
-            data_packet = (struct spi_data_packet *)rt_mp_alloc(&wifi_device->spi_tx_mp, RT_WAITING_FOREVER);
-            // TODO: check result.
-
-            wifi_cmd = (struct spi_wifi_cmd *)data_packet->buffer;
-            wifi_cmd->cmd = SPI_WIFI_CMD_INIT;
-
-            data_packet->data_type = data_type_cmd;
-            data_packet->data_len = member_offset(struct spi_wifi_cmd, buffer) + 0;
-
-            rt_mb_send(&wifi_device->spi_tx_mb, (rt_uint32_t)data_packet);
-            rt_event_send(&spi_wifi_data_event, 1);
-
-            result = rt_mb_recv(&wifi_device->spi_wifi_cmd_mb,
-                                (rt_uint32_t *)&resp,
-                                RT_WAITING_FOREVER);
-
-            if ((result == RT_EOK) && (resp != RT_NULL))
-            {
-                WIFI_DEBUG("resp cmd: %d\n", resp->cmd);
-
-                rt_memcpy(args, resp->buffer, 6);
-            }
-        }
-        else return -RT_ERROR;
-        break;
-
-
-    case SPI_WIFI_CMD_SCAN:
-
-    case SPI_WIFI_CMD_JOIN:
-        if (args)
-        {
-            struct cmd_join *cmd_join;
-
-            data_packet = (struct spi_data_packet *)rt_mp_alloc(&wifi_device->spi_tx_mp, RT_WAITING_FOREVER);
-
-            wifi_cmd = (struct spi_wifi_cmd *)data_packet->buffer;
-            wifi_cmd->cmd = SPI_WIFI_CMD_JOIN;
-            cmd_join = (struct cmd_join *)wifi_cmd->buffer;
-
-#define WPA_SECURITY    0x00200000
-#define WPA2_SECURITY   0x00400000
-
-#define TKIP_ENABLED    0x0002
-#define AES_ENABLED     0x0004
-
-
-            strncpy(cmd_join->ssid, SSID_NAME, SSID_NAME_LENGTH_MAX);
-            strncpy(cmd_join->passwd, SSID_PASSWORD, PASSWORD_LENGTH_MAX);
-            cmd_join->security = WPA_SECURITY | TKIP_ENABLED | AES_ENABLED;
-            // cmd_join->security = WPA_SECURITY | TKIP_ENABLED;
-            data_packet->data_type = data_type_cmd;
-            data_packet->data_len = sizeof(struct cmd_join) + member_offset(struct spi_wifi_cmd, buffer);
-
-            rt_mb_send(&wifi_device->spi_tx_mb, (rt_uint32_t)data_packet);
-            rt_event_send(&spi_wifi_data_event, 1);
-        }
-        else return -RT_ERROR;
-        break;
-
-    default :
-        break;
+    }
+    else
+    {
+        result = rw009_cmd(wifi_device, cmd, args);
     }
 
-    return RT_EOK;
+    return result;
 }
 
 /* transmit packet. */
-rt_err_t spi_wifi_eth_tx(rt_device_t dev, struct pbuf *p)
+rt_err_t rw009_wifi_tx(rt_device_t dev, struct pbuf *p)
 {
     rt_err_t result = RT_EOK;
     struct spi_data_packet *data_packet;
-    struct spi_wifi_eth *wifi_device = (struct spi_wifi_eth *)dev;
+    struct rw009_wifi *wifi_device = (struct rw009_wifi *)dev;
 
     if (!wifi_device->active)
     {
@@ -441,10 +558,10 @@ rt_err_t spi_wifi_eth_tx(rt_device_t dev, struct pbuf *p)
 }
 
 /* reception packet. */
-struct pbuf *spi_wifi_eth_rx(rt_device_t dev)
+struct pbuf *rw009_wifi_rx(rt_device_t dev)
 {
     struct pbuf *p = RT_NULL;
-    struct spi_wifi_eth *wifi_device = (struct spi_wifi_eth *)dev;
+    struct rw009_wifi *wifi_device = (struct rw009_wifi *)dev;
 
     if (rt_mb_recv(&wifi_device->eth_rx_mb, (rt_uint32_t *)&p, 0) != RT_EOK)
     {
@@ -452,12 +569,13 @@ struct pbuf *spi_wifi_eth_rx(rt_device_t dev)
     }
 
 #ifdef ETH_RX_DUMP
-	if(p)
-		packet_dump("RX dump", p);
+    if(p)
+        packet_dump("RX dump", p);
 #endif /* ETH_RX_DUMP */
 
     return p;
 }
+/********************************* RT-Thread Ethernet interface end **************************************/
 
 static void spi_wifi_data_thread_entry(void *parameter)
 {
@@ -476,7 +594,7 @@ static void spi_wifi_data_thread_entry(void *parameter)
             continue;
         }
 
-        result = spi_wifi_transfer(&spi_wifi_device);
+        result = spi_wifi_transfer(&rw009_wifi_device);
 
         if (result == RT_EOK)
         {
@@ -487,13 +605,17 @@ static void spi_wifi_data_thread_entry(void *parameter)
 
 rt_err_t rt_hw_wifi_init(const char *spi_device_name)
 {
-    memset(&spi_wifi_device, 0, sizeof(struct spi_wifi_eth));
+    /* align and struct size check. */
+    RT_ASSERT( (SPI_MAX_DATA_LEN & 0x03) == 0);
+    RT_ASSERT( sizeof(struct rw009_resp) <= SPI_MAX_DATA_LEN);
+
+    memset(&rw009_wifi_device, 0, sizeof(struct rw009_wifi));
 
-    spi_wifi_device.rt_spi_device = (struct rt_spi_device *)rt_device_find(spi_device_name);
+    rw009_wifi_device.rt_spi_device = (struct rt_spi_device *)rt_device_find(spi_device_name);
 
-    if (spi_wifi_device.rt_spi_device == RT_NULL)
+    if (rw009_wifi_device.rt_spi_device == RT_NULL)
     {
-        WIFI_DEBUG("spi device %s not found!\r\n", spi_device_name);
+        SPI_DEBUG("spi device %s not found!\r\n", spi_device_name);
         return -RT_ENOSYS;
     }
 
@@ -502,49 +624,49 @@ rt_err_t rt_hw_wifi_init(const char *spi_device_name)
         struct rt_spi_configuration cfg;
         cfg.data_width = 8;
         cfg.mode = RT_SPI_MODE_0 | RT_SPI_MSB; /* SPI Compatible: Mode 0. */
-        cfg.max_hz = 15 * 1000000; /* 30M */
-        rt_spi_configure(spi_wifi_device.rt_spi_device, &cfg);
+        cfg.max_hz = 15 * 1000000; /* 10M */
+        rt_spi_configure(rw009_wifi_device.rt_spi_device, &cfg);
     }
 
-    spi_wifi_device.parent.parent.init       = spi_wifi_eth_init;
-    spi_wifi_device.parent.parent.open       = spi_wifi_eth_open;
-    spi_wifi_device.parent.parent.close      = spi_wifi_eth_close;
-    spi_wifi_device.parent.parent.read       = spi_wifi_eth_read;
-    spi_wifi_device.parent.parent.write      = spi_wifi_eth_write;
-    spi_wifi_device.parent.parent.control    = spi_wifi_eth_control;
-    spi_wifi_device.parent.parent.user_data  = RT_NULL;
+    rw009_wifi_device.parent.parent.init       = rw009_wifi_init;
+    rw009_wifi_device.parent.parent.open       = rw009_wifi_open;
+    rw009_wifi_device.parent.parent.close      = rw009_wifi_close;
+    rw009_wifi_device.parent.parent.read       = rw009_wifi_read;
+    rw009_wifi_device.parent.parent.write      = rw009_wifi_write;
+    rw009_wifi_device.parent.parent.control    = rw009_wifi_control;
+    rw009_wifi_device.parent.parent.user_data  = RT_NULL;
 
-    spi_wifi_device.parent.eth_rx     = spi_wifi_eth_rx;
-    spi_wifi_device.parent.eth_tx     = spi_wifi_eth_tx;
+    rw009_wifi_device.parent.eth_rx     = rw009_wifi_rx;
+    rw009_wifi_device.parent.eth_tx     = rw009_wifi_tx;
 
-    rt_mp_init(&spi_wifi_device.spi_tx_mp,
+    rt_mp_init(&rw009_wifi_device.spi_tx_mp,
                "spi_tx",
-               &spi_wifi_device.spi_tx_mempool[0],
-               sizeof(spi_wifi_device.spi_tx_mempool),
+               &rw009_wifi_device.spi_tx_mempool[0],
+               sizeof(rw009_wifi_device.spi_tx_mempool),
                sizeof(struct spi_data_packet));
 
-    rt_mp_init(&spi_wifi_device.spi_rx_mp,
+    rt_mp_init(&rw009_wifi_device.spi_rx_mp,
                "spi_rx",
-               &spi_wifi_device.spi_rx_mempool[0],
-               sizeof(spi_wifi_device.spi_rx_mempool),
+               &rw009_wifi_device.spi_rx_mempool[0],
+               sizeof(rw009_wifi_device.spi_rx_mempool),
                sizeof(struct spi_data_packet));
 
-    rt_mb_init(&spi_wifi_device.spi_tx_mb,
+    rt_mb_init(&rw009_wifi_device.spi_tx_mb,
                "spi_tx",
-               &spi_wifi_device.spi_tx_mb_pool[0],
+               &rw009_wifi_device.spi_tx_mb_pool[0],
                SPI_TX_POOL_SIZE,
                RT_IPC_FLAG_PRIO);
 
-    rt_mb_init(&spi_wifi_device.eth_rx_mb,
+    rt_mb_init(&rw009_wifi_device.eth_rx_mb,
                "eth_rx",
-               &spi_wifi_device.eth_rx_mb_pool[0],
+               &rw009_wifi_device.eth_rx_mb_pool[0],
                SPI_TX_POOL_SIZE,
                RT_IPC_FLAG_PRIO);
 
-    rt_mb_init(&spi_wifi_device.spi_wifi_cmd_mb,
+    rt_mb_init(&rw009_wifi_device.rw009_cmd_mb,
                "wifi_cmd",
-               &spi_wifi_device.spi_wifi_cmd_mb_pool[0],
-               sizeof(spi_wifi_device.spi_wifi_cmd_mb_pool) / 4,
+               &rw009_wifi_device.rw009_cmd_mb_pool[0],
+               sizeof(rw009_wifi_device.rw009_cmd_mb_pool) / 4,
                RT_IPC_FLAG_PRIO);
     rt_event_init(&spi_wifi_data_event, "wifi", RT_IPC_FLAG_FIFO);
 
@@ -567,24 +689,16 @@ rt_err_t rt_hw_wifi_init(const char *spi_device_name)
 
     /* init: get mac address */
     {
-        WIFI_DEBUG("wifi_control SPI_WIFI_CMD_INIT\n");
-        spi_wifi_eth_control((rt_device_t)&spi_wifi_device,
-                             SPI_WIFI_CMD_INIT,
-                             (void *)&spi_wifi_device.dev_addr[0]);
+        WIFI_DEBUG("wifi_control RW009_CMD_INIT\n");
+        rw009_wifi_control((rt_device_t)&rw009_wifi_device,
+                           RW009_CMD_INIT,
+                           (void *)1); // 0: firmware, 1: STA, 2:AP
 
     }
-    /* register eth device */
-    eth_device_init(&(spi_wifi_device.parent), "w0");
-    eth_device_linkchange(&spi_wifi_device.parent, RT_FALSE);
-
-    {
-        WIFI_DEBUG("wifi_control SPI_WIFI_CMD_JOIN\n");
-        spi_wifi_eth_control((rt_device_t)&spi_wifi_device,
-                             SPI_WIFI_CMD_JOIN,
-                             (void *)&spi_wifi_device.dev_addr[0]);
 
-        WIFI_DEBUG("wifi_control exit\n");
-    }
+    /* register eth device */
+    eth_device_init(&(rw009_wifi_device.parent), "w0");
+    eth_device_linkchange(&rw009_wifi_device.parent, RT_FALSE);
 
     return RT_EOK;
 }
@@ -594,9 +708,93 @@ void spi_wifi_isr(int vector)
     /* enter interrupt */
     rt_interrupt_enter();
 
-    WIFI_DEBUG("spi_wifi_isr\n");
+    SPI_DEBUG("spi_wifi_isr\n");
     rt_event_send(&spi_wifi_data_event, 1);
 
     /* leave interrupt */
     rt_interrupt_leave();
 }
+
+/********************************* RW009 tools **************************************/
+rt_err_t rw009_join(const char * SSID, const char * passwd)
+{
+    rt_err_t result;
+    rt_device_t wifi_device;
+    rw009_cmd_easy_join easy_join;
+
+    wifi_device = rt_device_find("w0");
+    if(wifi_device == RT_NULL)
+        return -RT_ENOSYS;
+
+    strncpy( easy_join.ssid, SSID, sizeof(easy_join.ssid) );
+    strncpy( easy_join.passwd, passwd, sizeof(easy_join.passwd) );
+
+    result = rt_device_control(wifi_device,
+                               RW009_CMD_EASY_JOIN,
+                               (void *)&easy_join);
+
+    return result;
+}
+
+int32_t rw009_rssi(void)
+{
+    rt_err_t result;
+    struct rw009_wifi * wifi_device;
+
+    wifi_device = (struct rw009_wifi *)rt_device_find("w0");
+
+    if(wifi_device == RT_NULL)
+        return 0;
+
+    if(wifi_device->active == 0)
+        return 0;
+
+    // SCAN
+    result = rt_device_control((rt_device_t)wifi_device,
+                               RW009_CMD_RSSI,
+                               RT_NULL);
+
+    if(result == RT_EOK)
+    {
+        return wifi_device->ap_info.rssi;
+    }
+
+    return 0;
+}
+
+#ifdef RT_USING_FINSH
+#include <finsh.h>
+
+static rt_err_t rw009_scan(void)
+{
+    rt_err_t result;
+    struct rw009_wifi * wifi_device;
+
+    wifi_device = (struct rw009_wifi *)rt_device_find("w0");
+
+    rt_kprintf("\nCMD RW009_CMD_SCAN \n");
+    result = rt_device_control((rt_device_t)wifi_device,
+                               RW009_CMD_SCAN,
+                               RT_NULL);
+
+    rt_kprintf("CMD RW009_CMD_SCAN result:%d\n", result);
+
+    if(result == RT_EOK)
+    {
+        uint32_t i;
+        rw009_ap_info *ap_info;
+
+        for(i=0; i<wifi_device->ap_scan_count; i++)
+        {
+            ap_info = &wifi_device->ap_scan[i];
+            rt_kprintf("AP #%02d SSID: %-32.32s\n", i, ap_info->ssid );
+        }
+    }
+
+    return result;
+}
+FINSH_FUNCTION_EXPORT(rw009_scan, SACN and list AP.);
+FINSH_FUNCTION_EXPORT(rw009_join, RW009 join to AP.);
+FINSH_FUNCTION_EXPORT(rw009_rssi, get RW009 current AP rssi.);
+
+#endif // RT_USING_FINSH

+ 84 - 36
components/drivers/spi/spi_wifi_rw009.h

@@ -20,6 +20,7 @@
  * Change Logs:
  * Date           Author       Notes
  * 2014-07-31     aozima       the first version
+ * 2014-09-18     aozima       update command & response.
  */
 
 #ifndef SPI_WIFI_H_INCLUDED
@@ -28,7 +29,7 @@
 #include <stdint.h>
 
 // little-endian
-struct cmd_request
+struct spi_cmd_request
 {
     uint32_t flag;
     uint32_t M2S_len; // master to slave data len.
@@ -42,7 +43,7 @@ struct cmd_request
 #define CMD_FLAG_MRDY       (0x01)
 
 // little-endian
-struct response
+struct spi_response
 {
     uint32_t flag;
     uint32_t S2M_len; // slave to master data len.
@@ -55,20 +56,16 @@ struct response
 #define RESP_MAGIC2         (0x10325476)
 
 /* spi slave configure. */
-#define MAX_DATA_LEN        1520
+#define SPI_MAX_DATA_LEN    1520
 #define SPI_TX_POOL_SIZE    2
 #define SPI_RX_POOL_SIZE    2
 
-// align check
-#if (MAX_DATA_LEN & 0x03) != 0
-#error MAX_DATA_LEN must ALIGN to 4byte!
-#endif
-
 typedef enum
 {
     data_type_eth_data = 0,
     data_type_cmd,
     data_type_resp,
+    data_type_status,
 }
 app_data_type_typedef;
 
@@ -76,52 +73,103 @@ struct spi_data_packet
 {
     uint32_t data_len;
     uint32_t data_type;
-    char buffer[MAX_DATA_LEN];
+    char buffer[SPI_MAX_DATA_LEN];
 };
 
-/* tools */
-#define node_entry(node, type, member) \
-    ((type *)((char *)(node) - (unsigned long)(&((type *)0)->member)))
-#define member_offset(type, member) \
-    ((unsigned long)(&((type *)0)->member))
+/********************************* RW009 **************************************/
 
-#define MAX_SPI_PACKET_SIZE    (member_offset(struct spi_data_packet, buffer) + MAX_DATA_LEN)
+/* option */
+#define RW009_CMD_TIMEOUT           (RT_TICK_PER_SECOND*3)
+#define SSID_NAME_LENGTH_MAX        (32)
+#define PASSWORD_LENGTH_MAX         (64)
 
-/********************************* RW009 **************************************/
+typedef struct _rw009_ap_info
+{
+    char        ssid[SSID_NAME_LENGTH_MAX];
+    uint8_t     bssid[8]; // 6byte + 2byte PAD.
+    int         rssi;               /* Receive Signal Strength Indication in dBm. */
+    uint32_t    max_data_rate;      /* Maximum data rate in kilobits/s */
+    uint32_t    security;           /* Security type  */
+    uint32_t    channel;            /* Radio channel that the AP beacon was received on   */
+} rw009_ap_info;
+
+typedef struct _rw009_cmd_init
+{
+    uint32_t mode;
+} rw009_cmd_init;
+
+typedef struct _rw009_resp_init
+{
+    uint8_t mac[8];     // 6byte + 2byte PAD.
+    uint8_t sn[24];     // serial.
+    char version[16];   // firmware version.
+} rw009_resp_init;
+
+typedef struct _rw009_cmd_easy_join
+{
+    char ssid[SSID_NAME_LENGTH_MAX];
+    char passwd[PASSWORD_LENGTH_MAX];
+} rw009_cmd_easy_join;
+
+typedef struct _rw009_cmd_join
+{
+    uint8_t bssid[8]; // 6byte + 2byte PAD.
+    char passwd[PASSWORD_LENGTH_MAX];
+} rw009_cmd_join;
 
-struct spi_wifi_cmd
+typedef struct _rw009_cmd_rssi
+{
+    uint8_t bssid[8]; // 6byte + 2byte PAD.
+} rw009_cmd_rssi;
+
+typedef struct _rw009_resp_join
+{
+    rw009_ap_info ap_info;
+} rw009_resp_join;
+
+struct rw009_cmd
 {
     uint32_t cmd;
-    char buffer[128];
+    uint32_t len;
+
+    /** command body */
+    union
+    {
+        rw009_cmd_init init;
+        rw009_cmd_easy_join easy_join;
+        rw009_cmd_join join;
+        rw009_cmd_rssi rssi;
+    } params;
 };
 
-struct spi_wifi_resp
+struct rw009_resp
 {
     uint32_t cmd;
-    char buffer[128];
+    uint32_t len;
+
+    int32_t result; // result for CMD.
+
+    /** resp Body */
+    union
+    {
+        rw009_resp_init init;
+        rw009_ap_info ap_info;
+    } resp;
 };
 
-#define SPI_WIFI_CMD_INIT         128  //wait
-#define SPI_WIFI_CMD_SCAN         129  //no wait
-#define SPI_WIFI_CMD_JOIN         130  //no wait
+#define RW009_CMD_INIT              128
+#define RW009_CMD_SCAN              129
+#define RW009_CMD_JOIN              130
+#define RW009_CMD_EASY_JOIN         131
+#define RW009_CMD_RSSI              132
 
 /* porting */
 extern void spi_wifi_hw_init(void);
 extern void spi_wifi_int_cmd(rt_bool_t cmd);
 extern rt_bool_t spi_wifi_is_busy(void);
 
-#define SSID_NAME_LENGTH_MAX        (32)
-#define PASSWORD_LENGTH_MAX         (32)
-
-struct cmd_join
-{
-    char ssid[SSID_NAME_LENGTH_MAX];
-    char passwd[PASSWORD_LENGTH_MAX];
-
-    uint8_t bssid[8]; // 6byte + 2byte PAD.
-
-    uint32_t channel;
-    uint32_t security;
-};
+/* export API. */
+extern int32_t rw009_rssi(void);
+extern rt_err_t rw009_join(const char * SSID, const char * passwd);
 
 #endif // SPI_WIFI_H_INCLUDED