Added support for the WNC M14A2A Cellular LTE Data Module.

Dependencies:   WNC14A2AInterface

Easy Connect

Easily add all supported connectivity methods to your mbed OS project

This project is derived from https://developer.mbed.org/teams/sandbox/code/simple-mbed-client-example/file/dd6231df71bb/easy-connect.lib. It give user the ability to switch between connectivity methods and includes support for the WNC14A2A Data Module. The `NetworkInterface` API makes this easy, but you still need a mechanism for the user to select the connection method, The selection is made by modifying the `mbed_app.json` file and using `easy_connect()` from your application.

Specifying connectivity method

To add support for the WNC14A2A, add the following to your ``mbed_app.json`` file:

mbed_app.json

{
    "config": {
        "network-interface":{
            "help": "options are ETHERNET,WIFI_ESP8266,WIFI_ODIN,MESH_LOWPAN_ND,MESH_THREAD,WNC14A2A",
            "value": "WNC14A2A"
        }
    },
}

After you choose `WNC14A2A` you'll also need to indicate if you want debug output or not by Enabling (true) or Disabling (false) WNC_DEBUG.

If WNC_DEBUG is enabled, there are 3 different levels of debug output (selected via bit settings). These debug levels are set using the following values:

ValueDescription
1Basic WNC driver debug output
2Comprehensive WNC driver debug output
4Network Layer debug output

You can have any combination of these three bit values for a total value of 0 – 7.

WNC Debug Settings

    "config": {
        "WNC_DEBUG": {
            "value": false
        },
        "WNC_DEBUG_SETTING": {
            "value": 4
        },
    }

Using Easy Connect from your application

Easy Connect has just one function which will either return a `NetworkInterface`-pointer or `NULL`:

Sample Code

#include "easy-connect.h"

int main(int, char**) {
    NetworkInterface* network = easy_connect(true); /* has 1 argument, enable_logging (pass in true to log to serial port) */
    if (!network) {
        printf("Connecting to the network failed... See serial output.\r\n");
        return 1;
    }
 
    // Rest of your program
}

Tested on

  • K64F with Ethernet.
  • AT&T Cellular IoT Starter Kit with WNC M14A2A Cellular Data Module

The WNCInterface class currently supports the following version(s):

  • MPSS: M14A2A_v11.50.164451 APSS: M14A2A_v11.53.164451

License

This library is released under the Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License and 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.

Committer:
group-Avnet
Date:
Wed Apr 19 01:08:11 2017 +0000
Revision:
0:478cfd88041f
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
group-Avnet 0:478cfd88041f 1 /**
group-Avnet 0:478cfd88041f 2 * @file BufferedSerial.cpp
group-Avnet 0:478cfd88041f 3 * @brief Software Buffer - Extends mbed Serial functionallity adding irq driven TX and RX
group-Avnet 0:478cfd88041f 4 * @author sam grove
group-Avnet 0:478cfd88041f 5 * @version 1.0
group-Avnet 0:478cfd88041f 6 * @see
group-Avnet 0:478cfd88041f 7 *
group-Avnet 0:478cfd88041f 8 * Copyright (c) 2013
group-Avnet 0:478cfd88041f 9 *
group-Avnet 0:478cfd88041f 10 * Licensed under the Apache License, Version 2.0 (the "License");
group-Avnet 0:478cfd88041f 11 * you may not use this file except in compliance with the License.
group-Avnet 0:478cfd88041f 12 * You may obtain a copy of the License at
group-Avnet 0:478cfd88041f 13 *
group-Avnet 0:478cfd88041f 14 * http://www.apache.org/licenses/LICENSE-2.0
group-Avnet 0:478cfd88041f 15 *
group-Avnet 0:478cfd88041f 16 * Unless required by applicable law or agreed to in writing, software
group-Avnet 0:478cfd88041f 17 * distributed under the License is distributed on an "AS IS" BASIS,
group-Avnet 0:478cfd88041f 18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
group-Avnet 0:478cfd88041f 19 * See the License for the specific language governing permissions and
group-Avnet 0:478cfd88041f 20 * limitations under the License.
group-Avnet 0:478cfd88041f 21 */
group-Avnet 0:478cfd88041f 22
group-Avnet 0:478cfd88041f 23 #include "BufferedSerial.h"
group-Avnet 0:478cfd88041f 24 #include <stdarg.h>
group-Avnet 0:478cfd88041f 25
group-Avnet 0:478cfd88041f 26 extern "C" int BufferedPrintfC(void *stream, int size, const char* format, va_list arg);
group-Avnet 0:478cfd88041f 27
group-Avnet 0:478cfd88041f 28 BufferedSerial::BufferedSerial(PinName tx, PinName rx, uint32_t buf_size, uint32_t tx_multiple, const char* name)
group-Avnet 0:478cfd88041f 29 : RawSerial(tx, rx) , _rxbuf(buf_size), _txbuf((uint32_t)(tx_multiple*buf_size))
group-Avnet 0:478cfd88041f 30 {
group-Avnet 0:478cfd88041f 31 RawSerial::attach(this, &BufferedSerial::rxIrq, Serial::RxIrq);
group-Avnet 0:478cfd88041f 32 this->_buf_size = buf_size;
group-Avnet 0:478cfd88041f 33 this->_tx_multiple = tx_multiple;
group-Avnet 0:478cfd88041f 34 return;
group-Avnet 0:478cfd88041f 35 }
group-Avnet 0:478cfd88041f 36
group-Avnet 0:478cfd88041f 37 BufferedSerial::~BufferedSerial(void)
group-Avnet 0:478cfd88041f 38 {
group-Avnet 0:478cfd88041f 39 RawSerial::attach(NULL, RawSerial::RxIrq);
group-Avnet 0:478cfd88041f 40 RawSerial::attach(NULL, RawSerial::TxIrq);
group-Avnet 0:478cfd88041f 41
group-Avnet 0:478cfd88041f 42 return;
group-Avnet 0:478cfd88041f 43 }
group-Avnet 0:478cfd88041f 44
group-Avnet 0:478cfd88041f 45 int BufferedSerial::readable(void)
group-Avnet 0:478cfd88041f 46 {
group-Avnet 0:478cfd88041f 47 return _rxbuf.available(); // note: look if things are in the buffer
group-Avnet 0:478cfd88041f 48 }
group-Avnet 0:478cfd88041f 49
group-Avnet 0:478cfd88041f 50 int BufferedSerial::writeable(void)
group-Avnet 0:478cfd88041f 51 {
group-Avnet 0:478cfd88041f 52 return 1; // buffer allows overwriting by design, always true
group-Avnet 0:478cfd88041f 53 }
group-Avnet 0:478cfd88041f 54
group-Avnet 0:478cfd88041f 55 int BufferedSerial::getc(void)
group-Avnet 0:478cfd88041f 56 {
group-Avnet 0:478cfd88041f 57 return _rxbuf;
group-Avnet 0:478cfd88041f 58 }
group-Avnet 0:478cfd88041f 59
group-Avnet 0:478cfd88041f 60 int BufferedSerial::putc(int c)
group-Avnet 0:478cfd88041f 61 {
group-Avnet 0:478cfd88041f 62 _txbuf = (char)c;
group-Avnet 0:478cfd88041f 63 BufferedSerial::prime();
group-Avnet 0:478cfd88041f 64
group-Avnet 0:478cfd88041f 65 return c;
group-Avnet 0:478cfd88041f 66 }
group-Avnet 0:478cfd88041f 67
group-Avnet 0:478cfd88041f 68 int BufferedSerial::puts(const char *s)
group-Avnet 0:478cfd88041f 69 {
group-Avnet 0:478cfd88041f 70 if (s != NULL) {
group-Avnet 0:478cfd88041f 71 const char* ptr = s;
group-Avnet 0:478cfd88041f 72
group-Avnet 0:478cfd88041f 73 while(*(ptr) != 0) {
group-Avnet 0:478cfd88041f 74 _txbuf = *(ptr++);
group-Avnet 0:478cfd88041f 75 }
group-Avnet 0:478cfd88041f 76 // _txbuf = '\n'; // done per puts definition
group-Avnet 0:478cfd88041f 77 BufferedSerial::prime();
group-Avnet 0:478cfd88041f 78
group-Avnet 0:478cfd88041f 79 return (ptr - s) + 1;
group-Avnet 0:478cfd88041f 80 }
group-Avnet 0:478cfd88041f 81 return 0;
group-Avnet 0:478cfd88041f 82 }
group-Avnet 0:478cfd88041f 83
group-Avnet 0:478cfd88041f 84 extern "C" size_t BufferedSerialThunk(void *buf_serial, const void *s, size_t length)
group-Avnet 0:478cfd88041f 85 {
group-Avnet 0:478cfd88041f 86 BufferedSerial *buffered_serial = (BufferedSerial *)buf_serial;
group-Avnet 0:478cfd88041f 87 return buffered_serial->write(s, length);
group-Avnet 0:478cfd88041f 88 }
group-Avnet 0:478cfd88041f 89
group-Avnet 0:478cfd88041f 90 int BufferedSerial::printf(const char* format, ...)
group-Avnet 0:478cfd88041f 91 {
group-Avnet 0:478cfd88041f 92 va_list arg;
group-Avnet 0:478cfd88041f 93 va_start(arg, format);
group-Avnet 0:478cfd88041f 94 int r = BufferedPrintfC((void*)this, this->_buf_size, format, arg);
group-Avnet 0:478cfd88041f 95 va_end(arg);
group-Avnet 0:478cfd88041f 96 return r;
group-Avnet 0:478cfd88041f 97 }
group-Avnet 0:478cfd88041f 98
group-Avnet 0:478cfd88041f 99 ssize_t BufferedSerial::write(const void *s, size_t length)
group-Avnet 0:478cfd88041f 100 {
group-Avnet 0:478cfd88041f 101 if (s != NULL && length > 0) {
group-Avnet 0:478cfd88041f 102 const char* ptr = (const char*)s;
group-Avnet 0:478cfd88041f 103 const char* end = ptr + length;
group-Avnet 0:478cfd88041f 104
group-Avnet 0:478cfd88041f 105 while (ptr != end) {
group-Avnet 0:478cfd88041f 106 _txbuf = *(ptr++);
group-Avnet 0:478cfd88041f 107 }
group-Avnet 0:478cfd88041f 108 BufferedSerial::prime();
group-Avnet 0:478cfd88041f 109
group-Avnet 0:478cfd88041f 110 return ptr - (const char*)s;
group-Avnet 0:478cfd88041f 111 }
group-Avnet 0:478cfd88041f 112 return 0;
group-Avnet 0:478cfd88041f 113 }
group-Avnet 0:478cfd88041f 114
group-Avnet 0:478cfd88041f 115
group-Avnet 0:478cfd88041f 116 void BufferedSerial::rxIrq(void)
group-Avnet 0:478cfd88041f 117 {
group-Avnet 0:478cfd88041f 118 // read from the peripheral and make sure something is available
group-Avnet 0:478cfd88041f 119 if(serial_readable(&_serial)) {
group-Avnet 0:478cfd88041f 120 _rxbuf = serial_getc(&_serial); // if so load them into a buffer
group-Avnet 0:478cfd88041f 121 // trigger callback if necessary
group-Avnet 0:478cfd88041f 122 if (_cbs[RxIrq]) {
group-Avnet 0:478cfd88041f 123 _cbs[RxIrq]();
group-Avnet 0:478cfd88041f 124 }
group-Avnet 0:478cfd88041f 125 }
group-Avnet 0:478cfd88041f 126
group-Avnet 0:478cfd88041f 127 return;
group-Avnet 0:478cfd88041f 128 }
group-Avnet 0:478cfd88041f 129
group-Avnet 0:478cfd88041f 130 void BufferedSerial::txIrq(void)
group-Avnet 0:478cfd88041f 131 {
group-Avnet 0:478cfd88041f 132 // see if there is room in the hardware fifo and if something is in the software fifo
group-Avnet 0:478cfd88041f 133 while(serial_writable(&_serial)) {
group-Avnet 0:478cfd88041f 134 if(_txbuf.available()) {
group-Avnet 0:478cfd88041f 135 serial_putc(&_serial, (int)_txbuf.get());
group-Avnet 0:478cfd88041f 136 } else {
group-Avnet 0:478cfd88041f 137 // disable the TX interrupt when there is nothing left to send
group-Avnet 0:478cfd88041f 138 RawSerial::attach(NULL, RawSerial::TxIrq);
group-Avnet 0:478cfd88041f 139 // trigger callback if necessary
group-Avnet 0:478cfd88041f 140 if (_cbs[TxIrq]) {
group-Avnet 0:478cfd88041f 141 _cbs[TxIrq]();
group-Avnet 0:478cfd88041f 142 }
group-Avnet 0:478cfd88041f 143 break;
group-Avnet 0:478cfd88041f 144 }
group-Avnet 0:478cfd88041f 145 }
group-Avnet 0:478cfd88041f 146
group-Avnet 0:478cfd88041f 147 return;
group-Avnet 0:478cfd88041f 148 }
group-Avnet 0:478cfd88041f 149
group-Avnet 0:478cfd88041f 150 void BufferedSerial::prime(void)
group-Avnet 0:478cfd88041f 151 {
group-Avnet 0:478cfd88041f 152 // if already busy then the irq will pick this up
group-Avnet 0:478cfd88041f 153 if(serial_writable(&_serial)) {
group-Avnet 0:478cfd88041f 154 RawSerial::attach(NULL, RawSerial::TxIrq); // make sure not to cause contention in the irq
group-Avnet 0:478cfd88041f 155 BufferedSerial::txIrq(); // only write to hardware in one place
group-Avnet 0:478cfd88041f 156 RawSerial::attach(this, &BufferedSerial::txIrq, RawSerial::TxIrq);
group-Avnet 0:478cfd88041f 157 }
group-Avnet 0:478cfd88041f 158
group-Avnet 0:478cfd88041f 159 return;
group-Avnet 0:478cfd88041f 160 }
group-Avnet 0:478cfd88041f 161
group-Avnet 0:478cfd88041f 162 void BufferedSerial::attach(Callback<void()> func, IrqType type)
group-Avnet 0:478cfd88041f 163 {
group-Avnet 0:478cfd88041f 164 _cbs[type] = func;
group-Avnet 0:478cfd88041f 165 }
group-Avnet 0:478cfd88041f 166