test

Dependents:   mbed-os-example-blinky-1stDevDemo

Revision:
0:79ce2b184a43
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SPWFSAxx.h	Wed May 23 14:37:10 2018 +0000
@@ -0,0 +1,446 @@
+/* SPWFSAxx Devices
+ * Copyright (c) 2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ 
+#ifndef SPWFSAXX_H
+#define SPWFSAXX_H
+
+#include "mbed.h"
+#include "ATCmdParser.h"
+#include "BlockExecuter.h"
+
+/* Common SPWFSAxx macros */
+#define SPWFXX_WINDS_LOW_ON         "0x00000000"
+#define SPWFXX_DEFAULT_BAUD_RATE    115200
+#define SPWFXX_MAX_TRIALS           3
+
+#if !defined(SPWFSAXX_RTS_PIN)
+#define SPWFSAXX_RTS_PIN    NC
+#endif // !defined(SPWFSAXX_RTS_PIN)
+#if !defined(SPWFSAXX_CTS_PIN)
+#define SPWFSAXX_CTS_PIN    NC
+#endif // !defined(SPWFSAXX_CTS_PIN)
+
+#define SPWFXX_ERR_OK               (+1)
+#define SPWFXX_ERR_OOM              (-1)
+#define SPWFXX_ERR_READ             (-2)
+#define SPWFXX_ERR_LEN              (-3)
+
+
+/* Max number of sockets & packets */
+#define SPWFSA_SOCKET_COUNT         (8)
+#define SPWFSA_MAX_PACKETS          (4)
+
+#define PENDING_DATA_SLOTS          (13)
+
+/* Pending data packets size buffer */
+class SpwfRealPendingPackets {
+public:
+    SpwfRealPendingPackets() {
+        reset();
+    }
+
+    void add(uint32_t new_cum_size) {
+        MBED_ASSERT(new_cum_size >= cumulative_size);
+
+        if(new_cum_size == cumulative_size) {
+            /* nothing to do */
+            return;
+        }
+
+        /* => `new_cum_size > cumulative_size` */
+        real_pkt_sizes[last_pkt_ptr] = (uint16_t)(new_cum_size - cumulative_size);
+        cumulative_size = new_cum_size;
+
+        last_pkt_ptr = (last_pkt_ptr + 1) % PENDING_DATA_SLOTS;
+
+        MBED_ASSERT(first_pkt_ptr != last_pkt_ptr);
+    }
+
+    uint32_t get(void) {
+        if(empty()) return 0;
+
+        return real_pkt_sizes[first_pkt_ptr];
+    }
+
+    uint32_t cumulative(void) {
+        return cumulative_size;
+    }
+
+    uint32_t remove(uint32_t size) {
+        MBED_ASSERT(!empty());
+
+        uint32_t ret = real_pkt_sizes[first_pkt_ptr];
+        first_pkt_ptr = (first_pkt_ptr + 1) % PENDING_DATA_SLOTS;
+
+        MBED_ASSERT(ret == size);
+        MBED_ASSERT(ret <= cumulative_size);
+        cumulative_size -= ret;
+
+        return ret;
+    }
+
+    void reset(void) {
+        memset(this, 0, sizeof(*this));
+    }
+
+private:
+    bool empty(void) {
+        if(first_pkt_ptr == last_pkt_ptr) {
+            MBED_ASSERT(cumulative_size == 0);
+            return true;
+        }
+        return false;
+    }
+
+    uint16_t real_pkt_sizes[PENDING_DATA_SLOTS];
+    uint8_t  first_pkt_ptr;
+    uint8_t  last_pkt_ptr;
+    uint32_t cumulative_size;
+};
+
+class SpwfSAInterface;
+
+/** SPWFSAxx Interface class.
+    This is an interface to a SPWFSAxx module.
+ */
+class SPWFSAxx
+{
+private:
+    /* abstract class*/
+    SPWFSAxx(PinName tx, PinName rx, PinName rts, PinName cts,
+             SpwfSAInterface &ifce, bool debug,
+             PinName wakeup, PinName reset);
+
+public:
+    /**
+     * Init the SPWFSAxx
+     *
+     * @param mode mode in which to startup
+     * @return true only if SPWFSAxx has started up correctly
+     */
+    bool startup(int mode);
+
+    /**
+     * Connect SPWFSAxx to AP
+     *
+     * @param ap the name of the AP
+     * @param passPhrase the password of AP
+     * @param securityMode the security mode of AP (WPA/WPA2, WEP, Open)
+     * @return true only if SPWFSAxx is connected successfully
+     */
+    bool connect(const char *ap, const char *passPhrase, int securityMode);
+
+    /**
+     * Disconnect SPWFSAxx from AP
+     *
+     * @return true only if SPWFSAxx is disconnected successfully
+     */
+    bool disconnect(void);
+
+    /**
+     * Get the IP address of SPWFSAxx
+     *
+     * @return null-terminated IP address or null if no IP address is assigned
+     */
+    const char *getIPAddress(void);
+
+    /**
+     * Get the MAC address of SPWFSAxx
+     *
+     * @return null-terminated MAC address or null if no MAC address is assigned
+     */
+    const char *getMACAddress(void);
+
+    /** Get the local gateway
+     *
+     *  @return         Null-terminated representation of the local gateway
+     *                  or null if no network mask has been received
+     */
+    const char *getGateway(void);
+
+    /** Get the local network mask
+     *
+     *  @return         Null-terminated representation of the local network mask
+     *                  or null if no network mask has been received
+     */
+    const char *getNetmask(void);
+
+    /** Gets the current radio signal strength for active connection
+     *
+     * @return          Connection strength in dBm (negative value)
+     */
+    int8_t getRssi();
+
+    /**
+     * Sends data to an open socket
+     *
+     * @param spwf_id module id of socket to send to
+     * @param data data to be sent
+     * @param amount amount of data to be sent - max 1024
+     * @param internal_id driver id of socket to send to
+     * @return number of written bytes on success, negative on failure
+     */
+    nsapi_size_or_error_t send(int spwf_id, const void *data, uint32_t amount, int internal_id);
+
+    /**
+     * Receives data from an open socket
+     *
+     * @param id id to receive from
+     * @param data placeholder for returned information
+     * @param amount number of bytes to be received
+     * @param datagram receive a datagram packet
+     * @return the number of bytes received
+     */
+    int32_t recv(int id, void *data, uint32_t amount, bool datagram);
+
+    /**
+     * Closes a socket
+     *
+     * @param id id of socket to close, valid only 0-4
+     * @return true only if socket is closed successfully
+     */
+    bool close(int id);
+
+    /**
+     * Allows timeout to be changed between commands
+     *
+     * @param timeout_ms timeout of the connection
+     */
+    void setTimeout(uint32_t timeout_ms);
+
+    /**
+     * Attach a function to call whenever network state has changed
+     *
+     * @param func A pointer to a void function, or 0 to set as none
+     */
+    void attach(Callback<void()> func);
+
+    /**
+     * Attach a function to call whenever network state has changed
+     *
+     * @param obj pointer to the object to call the member function on
+     * @param method pointer to the member function to call
+     */
+    template <typename T, typename M>
+    void attach(T *obj, M method) {
+        attach(Callback<void()>(obj, method));
+    }
+
+    static const char _cr_ = '\x0d'; // '\r' carriage return
+    static const char _lf_ = '\x0a'; // '\n' line feed
+
+private:
+    UARTSerial _serial;
+    ATCmdParser _parser;
+
+    DigitalOut _wakeup;
+    DigitalOut _reset;
+    PinName _rts;
+    PinName _cts;
+
+    int _timeout;
+    bool _dbg_on;
+
+    int _pending_sockets_bitmap;
+    SpwfRealPendingPackets _pending_pkt_sizes[SPWFSA_SOCKET_COUNT];
+
+    bool _network_lost_flag;
+    SpwfSAInterface &_associated_interface;
+
+    /**
+     * Reset SPWFSAxx
+     *
+     * @return true only if SPWFSAxx resets successfully
+     */
+    bool hw_reset(void);
+    bool reset(void);
+
+    /**
+     * Check if SPWFSAxx is connected
+     *
+     * @return true only if the chip has an IP address
+     */
+    bool isConnected(void);
+
+    /**
+     * Checks if data is available
+     */
+    bool readable(void) {
+        return _serial.FileHandle::readable();
+    }
+
+    /**
+     * Checks if data can be written
+     */
+    bool writeable(void) {
+        return _serial.FileHandle::writable();
+    }
+
+    /**
+     * Try to empty RX buffer
+     * Can be used when commands fail receiving expected response to try to recover situation
+     * @note Gives no guarantee that situation improves
+     */
+    void empty_rx_buffer(void) {
+        while(readable()) _parser.getc();
+    }
+
+    /* block calling (external) callback */
+    volatile unsigned int _call_event_callback_blocked;
+    Callback<void()> _callback_func;
+
+    struct packet {
+        struct packet *next;
+        int id;
+        uint32_t len;
+        // data follows
+    } *_packets, **_packets_end;
+
+    void _packet_handler_th(void);
+    void _execute_bottom_halves(void);
+    void _network_lost_handler_th(void);
+    void _network_lost_handler_bh(void);
+    void _hard_fault_handler(void);
+    void _wifi_hwfault_handler(void);
+    void _server_gone_handler(void);
+#if MBED_CONF_IDW0XX1_EXPANSION_BOARD == IDW04A1
+    void _skip_oob(void);
+#endif
+    bool _wait_wifi_hw_started(void);
+    bool _wait_console_active(void);
+    int _read_len(int);
+    int _flush_in(char*, int);
+    bool _winds_off(void);
+    void _winds_on(void);
+    void _read_in_pending(void);
+    int _read_in_pkt(int spwf_id, bool close);
+    int _read_in_packet(int spwf_id, uint32_t amount);
+    void _recover_from_hard_faults(void);
+    void _free_packets(int spwf_id);
+    void _free_all_packets(void);
+    void _process_winds();
+
+    virtual int _read_in(char*, int, uint32_t) = 0;
+
+    bool _recv_delim_lf(void) {
+        return (_parser.getc() == _lf_);
+    }
+
+    bool _recv_delim_cr(void) {
+        return (_parser.getc() == _cr_);
+    }
+
+    bool _recv_delim_cr_lf(void) {
+        return _recv_delim_cr() && _recv_delim_lf();
+    }
+
+    bool _recv_ok(void) {
+        return _parser.recv(SPWFXX_RECV_OK) && _recv_delim_lf();
+    }
+
+    void _add_pending_packet_sz(int spwf_id, uint32_t size);
+    void _add_pending_pkt_size(int spwf_id, uint32_t size) {
+        _pending_pkt_sizes[spwf_id].add(size);
+    }
+
+    uint32_t _get_cumulative_size(int spwf_id) {
+        return _pending_pkt_sizes[spwf_id].cumulative();
+    }
+
+    uint32_t _remove_pending_pkt_size(int spwf_id, uint32_t size) {
+        return _pending_pkt_sizes[spwf_id].remove(size);
+    }
+
+    uint32_t _get_pending_pkt_size(int spwf_id) {
+        return _pending_pkt_sizes[spwf_id].get();
+    }
+
+   void _reset_pending_pkt_sizes(int spwf_id) {
+        _pending_pkt_sizes[spwf_id].reset();
+    }
+
+   void _set_pending_data(int spwf_id) {
+       _pending_sockets_bitmap |= (1 << spwf_id);
+   }
+
+   void _clear_pending_data(int spwf_id) {
+        _pending_sockets_bitmap &= ~(1 << spwf_id);
+    }
+
+    bool _is_data_pending(int spwf_id) {
+        return (_pending_sockets_bitmap & (1 << spwf_id)) ? true : false;
+    }
+
+    bool _is_data_pending(void) {
+        if(_pending_sockets_bitmap != 0) return true;
+        else return false;
+    }
+
+    void _packet_handler_bh(void) {
+        /* read in other eventually pending packages */
+        _read_in_pending();
+    }
+
+    /* Do not call the (external) callback in IRQ context while performing critical module operations */
+    void _event_handler(void);
+
+    void _error_handler(void);
+
+    void _call_callback(void) {
+        if((bool)_callback_func) {
+            _callback_func();
+        }
+    }
+
+    bool _is_event_callback_blocked(void) {
+        return (_call_event_callback_blocked != 0);
+    }
+
+    void _block_event_callback(void) {
+        _call_event_callback_blocked++;
+    }
+
+    void _unblock_event_callback(void) {
+        MBED_ASSERT(_call_event_callback_blocked > 0);
+        _call_event_callback_blocked--;
+        if(_call_event_callback_blocked == 0) {
+            _trigger_event_callback();
+        }
+    }
+
+    /* trigger call of (external) callback in case there is still data */
+    void _trigger_event_callback(void) {
+        MBED_ASSERT(_call_event_callback_blocked == 0);
+        /* if still data available */
+        if(readable()) {
+            _call_callback();
+        }
+    }
+
+    char _ip_buffer[16];
+    char _gateway_buffer[16];
+    char _netmask_buffer[16];
+    char _mac_buffer[18];
+
+    char _msg_buffer[256];
+
+private:
+    friend class SPWFSA01;
+    friend class SPWFSA04;
+    friend class SpwfSAInterface;
+};
+
+#endif // SPWFSAXX_H