update RW009 wifi driver.
This commit is contained in:
parent
ab20554254
commit
3c99a5bf8d
|
@ -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 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 <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
|
||||
|
|
|
@ -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))
|
||||
|
||||
#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
|
||||
|
|
Loading…
Reference in New Issue