/*********************************************************************************************************************
* RT1064DVL6A Opensourec Library RT1064DVL6A Դ⣩һڹٷ SDK ӿڵĵԴ
* Copyright (c) 2022 SEEKFREE ɿƼ
* 
* ļ RT1064DVL6A Դһ
* 
* RT1064DVL6A Դ 
* Ըᷢ GPLGNU General Public License GNUͨù֤
*  GPL ĵ3棨 GPL3.0ѡģκκİ汾·/޸
* 
* Դķϣܷãδκεı֤
* ûԻʺض;ı֤
* ϸμ GPL
* 
* ӦյԴͬʱյһ GPL ĸ
* ûУ<https://www.gnu.org/licenses/>
* 
* ע
* Դʹ GPL3.0 Դ֤Э Ϊİ汾
* Ӣİ libraries/doc ļµ GPL3_permission_statement.txt ļ
* ֤ libraries ļ ļµ LICENSE ļ
* ӭλʹò ޸ʱ뱣ɿƼİȨ
* 
* ļ          zf_device_wifi_spi
* ˾          ɶɿƼ޹˾
* 汾Ϣ          鿴 libraries/doc ļ version ļ 汾˵
*           IAR 8.32.4 or MDK 5.33
* ƽ̨          RT1064DVL6A
*           https://seekfree.taobao.com/
* 
* ޸ļ¼
*                               ע
* 2022-09-21        SeekFree            first version
********************************************************************************************************************/
/*********************************************************************************************************************
* ߶壺
*                   ------------------------------------
*                   ģܽ            Ƭܽ
*                   RST                 鿴 zf_device_wifi_spi.h  WIFI_SPI_RST_PIN 궨
*                   INT                 鿴 zf_device_wifi_spi.h  WIFI_SPI_INT_PIN 궨
*                   CS                  鿴 zf_device_wifi_spi.h  WIFI_SPI_CS_PIN 궨
*                   MISO                鿴 zf_device_wifi_spi.h  WIFI_SPI_MISO_PIN 궨
*                   SCK                 鿴 zf_device_wifi_spi.h  WIFI_SPI_SCK_PIN 궨
*                   MOSI                鿴 zf_device_wifi_spi.h  WIFI_SPI_MOSI_PIN 궨
*                   5V                  5V Դ
*                   GND                 Դ
*                   
*                   ------------------------------------
*********************************************************************************************************************/

#include "stdio.h"
#include "zf_common_clock.h"
#include "zf_common_debug.h"
#include "zf_common_fifo.h"
#include "zf_driver_delay.h"
#include "zf_driver_gpio.h"
#include "zf_driver_spi.h"
#include "zf_device_type.h"

#include "zf_device_wifi_spi.h"

#define WIFI_CONNECT_TIME_OUT       10000       // λ
#define SOCKET_CONNECT_TIME_OUT     50000       // λ
#define OTHER_TIME_OUT              1000        // λ

char wifi_spi_version[12];                      // ģ̼汾Ϣ
char wifi_spi_mac_addr[20];                     // ģMACַϢ
char wifi_spi_ip_addr_port[25];                 // ģIPַ˿Ϣ

static fifo_struct  wifi_spi_fifo;
static uint8        wifi_spi_buffer[WIFI_SPI_RECVIVE_FIFO_SIZE];
static volatile     wifi_spi_state_enum wifi_spi_mutex;
//-------------------------------------------------------------------------------------------------------------------
//      ȴWIFI SPI
// ˵     wait_time       ȴʱ λ
// ز     uint8           ״̬ 0-ɹ 1-
// ʹʾ     ڲʹãû
// עϢ     
//-------------------------------------------------------------------------------------------------------------------
static uint8 wifi_spi_wait_idle (uint32 wait_time)
{
    uint32 time = 0;
    
    wait_time = wait_time*100;
    while(0 == gpio_get_level(WIFI_SPI_INT_PIN))
    {
        system_delay_us(10);
        time++;
        if(wait_time <= time)
        {
            break;
        }
    }
    return (wait_time <= time);
}

//-------------------------------------------------------------------------------------------------------------------
//      дݵWIFI SPI
// ˵     *buffer1        һҪ͵ݻַ
// ˵     length1         һݳ
// ˵     *buffer2        ڶҪ͵ݻַ
// ˵     length2         ڶݳ
// ز     void           
// ʹʾ     ڲʹãû
// עϢ     
//-------------------------------------------------------------------------------------------------------------------
static void wifi_spi_write (const uint8 *buffer1, uint16 length1, const uint8 *buffer2, uint16 length2)
{
    gpio_low(WIFI_SPI_CS_PIN);
    if(NULL != buffer1)
    {
        spi_write_8bit_array(WIFI_SPI_INDEX, buffer1, length1);
    }
    if(NULL != buffer2)
    {
        spi_write_8bit_array(WIFI_SPI_INDEX, buffer2, length2);
    }
    gpio_high(WIFI_SPI_CS_PIN);
}

//-------------------------------------------------------------------------------------------------------------------
//      WIFI SPI ͬʱУշ
// ˵     *packets        յĵַ
// ˵     length          Ҫյĳ
// ز     void           
// ʹʾ     ڲʹãû
// עϢ     
//-------------------------------------------------------------------------------------------------------------------
static void wifi_spi_transfer_command (wifi_spi_packets_struct *packets, uint16 length)
{
    gpio_low(WIFI_SPI_CS_PIN);
    
    spi_transfer_8bit(WIFI_SPI_INDEX, (uint8 *)&(packets->head), (uint8 *)&(packets->head), sizeof(wifi_spi_head_struct));
    
    if(length)
    {
        spi_transfer_8bit(WIFI_SPI_INDEX, (const uint8 *)(packets->buffer), packets->buffer, length);
    }
    
    gpio_high(WIFI_SPI_CS_PIN);
}

//-------------------------------------------------------------------------------------------------------------------
//      WIFI SPI ͬʱ(շ)
// ˵     *write_data     ͵ݻַ
// ˵     *read_data      յݵĴ洢ַ
// ˵     length          Ҫյĳ
// ز     void           
// ʹʾ     ڲʹãû
// עϢ     
//-------------------------------------------------------------------------------------------------------------------
static void wifi_spi_transfer_data (const uint8 *write_data, wifi_spi_packets_struct *read_data, uint16 length)
{
    gpio_low(WIFI_SPI_CS_PIN);
    
    read_data->head.command = WIFI_SPI_DATA;
    read_data->head.length  = length;
    
    spi_transfer_8bit(WIFI_SPI_INDEX, (uint8 *)&(read_data->head), (uint8 *)&(read_data->head), sizeof(wifi_spi_head_struct));
    
    if(WIFI_SPI_RECVIVE_SIZE < length)
    {
        spi_transfer_8bit(WIFI_SPI_INDEX, write_data, read_data->buffer, WIFI_SPI_RECVIVE_SIZE);
        spi_write_8bit_array(WIFI_SPI_INDEX, &write_data[WIFI_SPI_RECVIVE_SIZE], length - WIFI_SPI_RECVIVE_SIZE);
    }
    else
    {
        // Ҫ͵ݿȡwrite_dataԽ
        memcpy(read_data->buffer, write_data, length);
        spi_transfer_8bit(WIFI_SPI_INDEX, read_data->buffer, read_data->buffer, WIFI_SPI_RECVIVE_SIZE);
    }
    gpio_high(WIFI_SPI_CS_PIN);
}

//-------------------------------------------------------------------------------------------------------------------
//      WIFI SPI 
// ˵     command         
// ˵     *buffer         ַ
// ˵     length          
// ˵     wait_time       ȴʱ λ100΢
// ز     uint8           ״̬ 0-ɹ 1-
// ʹʾ     ڲʹãû
// עϢ     
//-------------------------------------------------------------------------------------------------------------------
static uint8 wifi_spi_set_parameter (wifi_spi_packets_command_enum command, uint8 *buffer, uint16 length, uint32 wait_time)
{
    uint8 return_state;
    wifi_spi_head_struct head;
    return_state = 1;
    do
    {
        head.command = command;
        head.length  = length;
        
        // ȴӻ׼
        if(wifi_spi_wait_idle(wait_time))
        {
            break;
        }

        wifi_spi_write(&head.command, sizeof(wifi_spi_head_struct), buffer, length);
        if(wifi_spi_wait_idle(wait_time))
        {
            break;
        }
        // Ӧź

        head.command = WIFI_SPI_DATA;
        head.length = 0;
        wifi_spi_transfer_command((wifi_spi_packets_struct *)&head, head.length);
        system_delay_us(20);
        if(WIFI_SPI_REPLY_OK == head.command)
        {
            return_state = 0;
        }
    }while(0);
    
    return return_state;
}

//-------------------------------------------------------------------------------------------------------------------
//      WIFI SPI ģϢȡ
// ˵     command         
// ˵     *buffer         յĲַ
// ˵     wait_time       ȴʱ λ100΢
// ز     uint8           ״̬ 0-ɹ 1-
// ʹʾ     ڲʹãû
// עϢ     
//-------------------------------------------------------------------------------------------------------------------
static uint8 wifi_spi_get_parameter (wifi_spi_packets_command_enum command, wifi_spi_packets_struct *read_data, uint32 wait_time)
{
    uint8 return_state;

    return_state = 1;
    do
    {
        // ȴӻ׼
        if(wifi_spi_wait_idle(wait_time))
        {
            break;
        }
        read_data->head.command = command;
        wifi_spi_write(&(read_data->head.command), WIFI_SPI_RECVIVE_SIZE, NULL, 0);

        if(wifi_spi_wait_idle(wait_time))
        {
            break;
        }
        read_data->head.command = WIFI_SPI_DATA;
        read_data->head.length = 0;
        wifi_spi_transfer_command(read_data, WIFI_SPI_RECVIVE_SIZE);
        return_state = 0;
    }while(0);
    return return_state;
}

//-------------------------------------------------------------------------------------------------------------------
//      WIFI SPI ̼汾ȡ
// ˵     void            ˿ں
// ز     uint8           ״̬ 0-ɹ 1-
// ʹʾ     
// עϢ     ú֮󣬹̼汾Ϣַʽwifi_spi_version
//-------------------------------------------------------------------------------------------------------------------
static uint8 wifi_spi_get_version (void)
{
    uint8 return_state;
    wifi_spi_packets_struct temp_packets;

    return_state = wifi_spi_get_parameter(WIFI_SPI_GET_VERSION, &temp_packets, OTHER_TIME_OUT);
    if((0 == return_state) && (WIFI_SPI_REPLY_VERSION == temp_packets.head.command))
    {
        memcpy(wifi_spi_version, temp_packets.buffer, temp_packets.head.length);
    }
    return return_state;
}

//-------------------------------------------------------------------------------------------------------------------
//      WIFI SPI MACַȡ
// ˵     void            ˿ں
// ز     uint8           ״̬ 0-ɹ 1-
// ʹʾ     
// עϢ     ú֮MACַϢַʽwifi_spi_mac_addr
//-------------------------------------------------------------------------------------------------------------------
static uint8 wifi_spi_get_mac_addr (void)
{
    uint8 return_state;
    wifi_spi_packets_struct temp_packets;

    return_state = wifi_spi_get_parameter(WIFI_SPI_GET_MAC_ADDR, &temp_packets, OTHER_TIME_OUT);
    if((0 == return_state) && (WIFI_SPI_REPLY_MAC_ADDR == temp_packets.head.command))
    {
        memcpy(wifi_spi_mac_addr, temp_packets.buffer, temp_packets.head.length);
    }
    return return_state;
}

//-------------------------------------------------------------------------------------------------------------------
//      WIFI SPI IPַ˿ںŻȡ
// ˵     void            ˿ں
// ز     uint8           ״̬ 0-ɹ 1-
// ʹʾ     
// עϢ     ú֮IPַ˿ںϢַʽwifi_spi_ip_addr_port
//              ҪSocket֮ô˺ȡϢ
//-------------------------------------------------------------------------------------------------------------------
static uint8 wifi_spi_get_ip_addr_port (void)
{
    uint8 return_state;
    wifi_spi_packets_struct temp_packets;

    return_state = wifi_spi_get_parameter(WIFI_SPI_GET_IP_ADDR, &temp_packets, OTHER_TIME_OUT);
    if((0 == return_state) && (WIFI_SPI_REPLY_IP_ADDR == temp_packets.head.command))
    {
        memcpy(wifi_spi_ip_addr_port, temp_packets.buffer, temp_packets.head.length);
    }
    return return_state;
}

//-------------------------------------------------------------------------------------------------------------------
//      WIFI SPI ӵWiFiϢWiFi
// ˵     *wifi_ssid      WIFI
// ˵     *pass_word      WIFI
// ز     uint8           ״̬ 0-ɹ 1-
// ʹʾ     wifi_spi_wifi_connect("SEEKFREE", "SEEKFREE123");
// עϢ     wifi_spi_wifi_connect("SEEKFREE", NULL); // ûWIFIȵ
//-------------------------------------------------------------------------------------------------------------------
uint8 wifi_spi_wifi_connect (char *wifi_ssid, char *pass_word)
{
    uint8 return_state;
    uint8 temp_buffer[64];
    uint16 length;
    
    if(NULL != pass_word)
    {
        // WIFIȵ뷢ȵ
        length = sprintf((char *)temp_buffer, "%s\r\n%s\r\n", wifi_ssid, pass_word);
    }
    else
    {
        // WIFIȵûֻҪȵ
        length = sprintf((char *)temp_buffer, "%s\r\n", wifi_ssid);
    }
    
    return_state = wifi_spi_set_parameter(WIFI_SPI_SET_WIFI_INFORMATION, temp_buffer, length, WIFI_CONNECT_TIME_OUT);
    
    // IPַ˿ںϢַʽwifi_spi_ip_addr_port
    wifi_spi_get_ip_addr_port();
    
    return return_state;
}

//-------------------------------------------------------------------------------------------------------------------
//      WIFI SPI ӵSocketϢSocket
// ˵     *transport_type 
// ˵     *ip_addr        IPַ
// ˵     *port           Ŀ˿ں
// ˵     *local_port     ˿ں
// ز     uint8           ״̬ 0-ɹ 1-
// ʹʾ     wifi_spi_socket_connect("TCP", "192.168.2.5", "8080", "6060");
// עϢ     
//-------------------------------------------------------------------------------------------------------------------
uint8 wifi_spi_socket_connect (char *transport_type, char *ip_addr, char *port, char *local_port)
{
    uint8 return_state;
    uint8 temp_buffer[41];
    uint16 length;
    
    length = sprintf((char *)temp_buffer, "%s\r\n%s\r\n%s\r\n%s\r\n", transport_type, ip_addr, port, local_port);
        
    return_state = wifi_spi_set_parameter(WIFI_SPI_SET_SOCKET_INFORMATION, temp_buffer, length, SOCKET_CONNECT_TIME_OUT);
    
    // IPַ˿ںϢַʽwifi_spi_ip_addr_port
    wifi_spi_get_ip_addr_port();
    
    return return_state;
}

//-------------------------------------------------------------------------------------------------------------------
//      WIFI SPI ϿSocket
// ˵     void            
// ز     uint8           ״̬ 0-ɹ 1-
// ʹʾ     wifi_spi_socket_disconnect();
// עϢ
//-------------------------------------------------------------------------------------------------------------------
uint8 wifi_spi_socket_disconnect (void)
{
    wifi_spi_packets_struct temp_packets;

    return wifi_spi_get_parameter(WIFI_SPI_CLOSE_SOCKET, &temp_packets, OTHER_TIME_OUT);
}

//-------------------------------------------------------------------------------------------------------------------
//      WIFI SPI λ
// ˵     void            
// ز     uint8           ״̬ 0-ɹ 1-
// ʹʾ     
// עϢ     
//-------------------------------------------------------------------------------------------------------------------
uint8 wifi_spi_reset (void)
{
    uint8 return_state;
    wifi_spi_head_struct head;
    return_state = 1;
    do
    {
        head.command = WIFI_SPI_RESET;
        head.length  = 0xA5A5;
        return_state = wifi_spi_wait_idle(OTHER_TIME_OUT);
        if(return_state)
        {
            break;
        }
        wifi_spi_write(&head.command, sizeof(wifi_spi_head_struct), NULL, 0);
    }while(0);
    
    return return_state;
}

//-------------------------------------------------------------------------------------------------------------------
//      WIFI SPI UDPģʽʱͺ
// ˵     void
// ز     uint8           ״̬ 0-ɹ 1-
// ʹʾ     
// עϢ     UDPģʽģյݺȴ2룬2δյͨsocket͵磬ϣݴϺô˺
//-------------------------------------------------------------------------------------------------------------------
uint8 wifi_spi_udp_send_now (void)
{
    uint8 return_state = 1;
    wifi_spi_packets_struct temp_packets;
    
    if(WIFI_SPI_IDLE == wifi_spi_mutex)
    {
        // ͨѶ״̬Ϊæ
        wifi_spi_mutex = WIFI_SPI_BUSY;
        do
        {
            if(wifi_spi_wait_idle(OTHER_TIME_OUT))
            {
                break;
            }

            // ʼsocket
            temp_packets.head.command = WIFI_SPI_UDP_SEND;
            temp_packets.head.length = 0;
            wifi_spi_transfer_command(&temp_packets, WIFI_SPI_RECVIVE_SIZE);
            
            // յİǷ
            if((WIFI_SPI_REPLY_DATA_START == temp_packets.head.command) || (WIFI_SPI_REPLY_DATA_END == temp_packets.head.command))
            {
                // յ
                if(temp_packets.head.length)
                {
                    fifo_write_buffer(&wifi_spi_fifo, temp_packets.buffer, temp_packets.head.length);
                }
            }
            
            // ȴӦź
            if(wifi_spi_wait_idle(OTHER_TIME_OUT))
            {
                break;
            }
            
            // Ӧź
            temp_packets.head.command = WIFI_SPI_DATA;
            temp_packets.head.length = 0;
            wifi_spi_transfer_command(&temp_packets, temp_packets.head.length);
            
            if(WIFI_SPI_REPLY_OK == temp_packets.head.command)
            {
                return_state = 0;
            }
            
        }while(0);
        
        // ͨѶ״̬Ϊ
        wifi_spi_mutex = WIFI_SPI_IDLE;
    } 
    
    return return_state;
}

//-------------------------------------------------------------------------------------------------------------------
//      WIFI SPI ݿ鷢ͺͬ
// ˵     *buff           Ҫ͵ݵַ
// ˵     length          ͳ
// ز     uint32          ʣδ͵ĳ
// ʹʾ     wifi_spi_send_buffer(buffer, 100);
// עϢ     
//-------------------------------------------------------------------------------------------------------------------
uint32 wifi_spi_send_buffer (const uint8 *buffer, uint32 length)
{
    uint16 send_length;
    wifi_spi_packets_struct temp_packets;
    
    // WIFI SPI״̬жϻ߳ѾͨѶ򱾴βܷ
    if(WIFI_SPI_IDLE == wifi_spi_mutex)
    {
        // ͨѶ״̬Ϊæ
        wifi_spi_mutex = WIFI_SPI_BUSY;
        
        while(length)
        {
            send_length = length > WIFI_SPI_TRANSFER_SIZE ? WIFI_SPI_TRANSFER_SIZE : length;
            
            if(wifi_spi_wait_idle(OTHER_TIME_OUT))
            {
                break;
            }
            
            wifi_spi_transfer_data(buffer, &temp_packets, send_length);
            
            // յİǷ
            if((WIFI_SPI_REPLY_DATA_START == temp_packets.head.command) || (WIFI_SPI_REPLY_DATA_END == temp_packets.head.command))
            {
                // յ
                if(temp_packets.head.length)
                {
                    fifo_write_buffer(&wifi_spi_fifo, temp_packets.buffer, temp_packets.head.length);
                }
            }
            
            length -= send_length;
            buffer += send_length;
        }
        
        // һεĽǷеݶ
        while(WIFI_SPI_REPLY_DATA_START == temp_packets.head.command)
        {
            if(wifi_spi_wait_idle(OTHER_TIME_OUT))
            {
                break;
            }
            
            // ȡģʣ
            temp_packets.head.command = WIFI_SPI_DATA;
            temp_packets.head.length  = 0;
            wifi_spi_transfer_command(&temp_packets, WIFI_SPI_RECVIVE_SIZE);
            // յİǷ
            if((WIFI_SPI_REPLY_DATA_START == temp_packets.head.command) || (WIFI_SPI_REPLY_DATA_END == temp_packets.head.command))
            {
                // յ
                if(temp_packets.head.length)
                {
                    fifo_write_buffer(&wifi_spi_fifo, temp_packets.buffer, temp_packets.head.length);
                }
            }
        }
        wifi_spi_mutex = WIFI_SPI_IDLE;
    }
    return length;
}

//-------------------------------------------------------------------------------------------------------------------
//      WIFI SPI ַͺͬ
// ˵     *string           Ҫ͵ַ
// ز     void          
// ʹʾ     wifi_spi_send_string("123", 100);
// עϢ     
//-------------------------------------------------------------------------------------------------------------------
void wifi_spi_send_string(const char *string)
{
    wifi_spi_send_buffer((uint8*)string, strlen(string));
}
    
//-------------------------------------------------------------------------------------------------------------------
//      WIFI SPI ȡ
// ˵     *buff           ջ
// ˵     length          ȡݳ
// ز     uint32          ʵʶȡݳ
// ʹʾ     wifi_spi_read_buffer(buffer, 100);
// עϢ     
//-------------------------------------------------------------------------------------------------------------------
uint32 wifi_spi_read_buffer (uint8 *buffer, uint32 length)
{
    zf_assert(NULL != buffer);
    uint32 data_len = length;
    
#if(1 == WIFI_SPI_READ_TRANSFER)
    
    wifi_spi_packets_struct temp_packets;
    // WIFI SPI״̬жϻ߳ѾͨѶ򱾴βܷ
    if(WIFI_SPI_IDLE == wifi_spi_mutex)
    {
        // ͨѶ״̬Ϊæ
        wifi_spi_mutex = WIFI_SPI_BUSY;
        
        // ͨѶ鿴ģǷδȡ
        do
        {
            if(wifi_spi_wait_idle(OTHER_TIME_OUT))
            {
                break;
            }
            temp_packets.head.command = WIFI_SPI_DATA;
            temp_packets.head.length  = 0;
            wifi_spi_transfer_command(&temp_packets, WIFI_SPI_RECVIVE_SIZE);
            // յİǷ
            if((WIFI_SPI_REPLY_DATA_START == temp_packets.head.command) || (WIFI_SPI_REPLY_DATA_END == temp_packets.head.command))
            {
                // յ
                if(temp_packets.head.length)
                {
                    fifo_write_buffer(&wifi_spi_fifo, temp_packets.buffer, temp_packets.head.length);
                }
            }
        }while(WIFI_SPI_REPLY_DATA_START == temp_packets.head.command);
        wifi_spi_mutex = WIFI_SPI_IDLE;
    }
#endif 
    
    fifo_read_buffer(&wifi_spi_fifo, buffer, &data_len, FIFO_READ_AND_CLEAN);
    return data_len;
}

//-------------------------------------------------------------------------------------------------------------------
//      WiFi ģʼ
// ˵     *wifi_ssid      Ŀӵ WiFi  ַʽ
// ˵     *pass_word      Ŀӵ WiFi  ַʽ
// ز     uint8           ģʼ״̬ 0-ɹ 1-
// ʹʾ     wifi_spi_init("SEEKFREE", "SEEKFREE123");
// עϢ     wifi_spi_init("SEEKFREE", NULL); // ûWIFIȵ
//-------------------------------------------------------------------------------------------------------------------
uint8 wifi_spi_init (char *wifi_ssid, char *pass_word)
{
    uint8 return_state = 0;
    
    fifo_init(&wifi_spi_fifo, FIFO_DATA_8BIT, wifi_spi_buffer, WIFI_SPI_RECVIVE_FIFO_SIZE);
    spi_init(WIFI_SPI_INDEX, SPI_MODE3, WIFI_SPI_SPEED, WIFI_SPI_SCK_PIN, WIFI_SPI_MOSI_PIN, WIFI_SPI_MISO_PIN, SPI_CS_NULL);//ӲSPIʼ
    gpio_init(WIFI_SPI_CS_PIN,  GPO, 1, GPO_PUSH_PULL);
    gpio_init(WIFI_SPI_RST_PIN, GPO, 1, GPO_PUSH_PULL);
    gpio_init(WIFI_SPI_INT_PIN, GPI, 0, GPI_PULL_DOWN);
    
    // λ
    gpio_set_level(WIFI_SPI_RST_PIN, 0);
    system_delay_ms(10);
    gpio_set_level(WIFI_SPI_RST_PIN, 1);
    
    // ȴģʼ
    system_delay_ms(100);
    wifi_spi_mutex = WIFI_SPI_IDLE;

    do
    {
        // ̼汾Ϣַʽwifi_spi_version
        return_state = wifi_spi_get_version();
        if(return_state)
        {
            break;
        }
        
        // MACַϢַʽwifi_spi_mac_addr
        wifi_spi_get_mac_addr();

        
        return_state = wifi_spi_wifi_connect(wifi_ssid, pass_word);
        if(return_state)
        {
            break;
        }
        
    #if(1 == WIFI_SPI_AUTO_CONNECT)
        return_state = wifi_spi_socket_connect("TCP", WIFI_SPI_TARGET_IP, WIFI_SPI_TARGET_PORT, WIFI_SPI_LOCAL_PORT);
        if(return_state)
        {
            break;
        }
    #endif
        
    #if(2 == WIFI_SPI_AUTO_CONNECT)
        return_state = wifi_spi_socket_connect("UDP", WIFI_SPI_TARGET_IP, WIFI_SPI_TARGET_PORT, WIFI_SPI_LOCAL_PORT);
        if(return_state)
        {
            break;
        }
    #endif
    }while(0);

    return return_state;
}
