From 3c99a5bf8dd3a0d978e5c94d998130e22decb02d Mon Sep 17 00:00:00 2001 From: aozima Date: Wed, 24 Sep 2014 12:08:01 +0800 Subject: [PATCH] update RW009 wifi driver. --- components/drivers/spi/spi_wifi_rw009.c | 562 ++++++++++++++++-------- components/drivers/spi/spi_wifi_rw009.h | 122 +++-- 2 files changed, 465 insertions(+), 219 deletions(-) diff --git a/components/drivers/spi/spi_wifi_rw009.c b/components/drivers/spi/spi_wifi_rw009.c index 4906a97712..501cce9015 100644 --- a/components/drivers/spi/spi_wifi_rw009.c +++ b/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 @@ -30,24 +31,33 @@ #include #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 spi_wifi_transfer(struct spi_wifi_eth *dev) +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 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); - spi_wifi_device.rt_spi_device = (struct rt_spi_device *)rt_device_find(spi_device_name); + memset(&rw009_wifi_device, 0, sizeof(struct rw009_wifi)); - if (spi_wifi_device.rt_spi_device == RT_NULL) + rw009_wifi_device.rt_spi_device = (struct rt_spi_device *)rt_device_find(spi_device_name); + + 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"); - } + 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 + +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; iap_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 diff --git a/components/drivers/spi/spi_wifi_rw009.h b/components/drivers/spi/spi_wifi_rw009.h index bb6fea5b01..2a1c6226fe 100644 --- a/components/drivers/spi/spi_wifi_rw009.h +++ b/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 // 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)) - -#define MAX_SPI_PACKET_SIZE (member_offset(struct spi_data_packet, buffer) + MAX_DATA_LEN) - /********************************* RW009 **************************************/ -struct spi_wifi_cmd +/* option */ +#define RW009_CMD_TIMEOUT (RT_TICK_PER_SECOND*3) +#define SSID_NAME_LENGTH_MAX (32) +#define PASSWORD_LENGTH_MAX (64) + +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; + +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