diff --git a/platform/BufferedSerial.cpp b/drivers/UARTSerial.cpp similarity index 77% rename from platform/BufferedSerial.cpp rename to drivers/UARTSerial.cpp index 6c2401be84..19d8174dbc 100644 --- a/platform/BufferedSerial.cpp +++ b/drivers/UARTSerial.cpp @@ -17,68 +17,68 @@ #if DEVICE_SERIAL #include -#include "platform/BufferedSerial.h" +#include "UARTSerial.h" #include "platform/mbed_poll.h" #include "platform/mbed_wait_api.h" namespace mbed { -BufferedSerial::BufferedSerial(PinName tx, PinName rx, int baud) : +UARTSerial::UARTSerial(PinName tx, PinName rx, int baud) : SerialBase(tx, rx, baud), _blocking(true), _tx_irq_enabled(false), - _dcd(NULL) + _dcd_irq(NULL) { /* Attatch IRQ routines to the serial device. */ - SerialBase::attach(callback(this, &BufferedSerial::rx_irq), RxIrq); + SerialBase::attach(callback(this, &UARTSerial::rx_irq), RxIrq); } -BufferedSerial::~BufferedSerial() +UARTSerial::~UARTSerial() { - delete _dcd; + delete _dcd_irq; } -void BufferedSerial::DCD_IRQ() +void UARTSerial::dcd_irq() { wake(); } -void BufferedSerial::set_data_carrier_detect(PinName DCD_pin, bool active_high) +void UARTSerial::set_data_carrier_detect(PinName dcd_pin, bool active_high) { - delete _dcd; - _dcd = NULL; + delete _dcd_irq; + _dcd_irq = NULL; - if (DCD_pin != NC) { - _dcd = new InterruptIn(DCD_pin); + if (dcd_pin != NC) { + _dcd_irq = new InterruptIn(dcd_pin); if (active_high) { - _dcd->fall(callback(this, &BufferedSerial::DCD_IRQ)); + _dcd_irq->fall(callback(this, &UARTSerial::dcd_irq)); } else { - _dcd->rise(callback(this, &BufferedSerial::DCD_IRQ)); + _dcd_irq->rise(callback(this, &UARTSerial::dcd_irq)); } } } -int BufferedSerial::close() +int UARTSerial::close() { /* Does not let us pass a file descriptor. So how to close ? * Also, does it make sense to close a device type file descriptor*/ return 0; } -int BufferedSerial::isatty() +int UARTSerial::isatty() { return 1; } -off_t BufferedSerial::seek(off_t offset, int whence) +off_t UARTSerial::seek(off_t offset, int whence) { /*XXX lseek can be done theoratically, but is it sane to mark positions on a dynamically growing/shrinking * buffer system (from an interrupt context) */ return -ESPIPE; } -int BufferedSerial::sync() +int UARTSerial::sync() { lock(); @@ -94,7 +94,7 @@ int BufferedSerial::sync() return 0; } -void BufferedSerial::sigio(Callback func) { +void UARTSerial::sigio(Callback func) { core_util_critical_section_enter(); _sigio_cb = func; if (_sigio_cb) { @@ -106,7 +106,7 @@ void BufferedSerial::sigio(Callback func) { core_util_critical_section_exit(); } -ssize_t BufferedSerial::write(const void* buffer, size_t length) +ssize_t UARTSerial::write(const void* buffer, size_t length) { size_t data_written = 0; const char *buf_ptr = static_cast(buffer); @@ -130,9 +130,9 @@ ssize_t BufferedSerial::write(const void* buffer, size_t length) core_util_critical_section_enter(); if (!_tx_irq_enabled) { - BufferedSerial::tx_irq(); // only write to hardware in one place + UARTSerial::tx_irq(); // only write to hardware in one place if (!_txbuf.empty()) { - SerialBase::attach(callback(this, &BufferedSerial::tx_irq), TxIrq); + SerialBase::attach(callback(this, &UARTSerial::tx_irq), TxIrq); _tx_irq_enabled = true; } } @@ -143,7 +143,7 @@ ssize_t BufferedSerial::write(const void* buffer, size_t length) return data_written; } -ssize_t BufferedSerial::read(void* buffer, size_t length) +ssize_t UARTSerial::read(void* buffer, size_t length) { size_t data_read = 0; @@ -171,19 +171,19 @@ ssize_t BufferedSerial::read(void* buffer, size_t length) return data_read; } -bool BufferedSerial::hup() const +bool UARTSerial::hup() const { - return _dcd && _dcd->read() != 0; + return _dcd_irq && _dcd_irq->read() != 0; } -void BufferedSerial::wake() +void UARTSerial::wake() { if (_sigio_cb) { _sigio_cb(); } } -short BufferedSerial::poll(short events) const { +short UARTSerial::poll(short events) const { short revents = 0; /* Check the Circular Buffer if space available for writing out */ @@ -205,17 +205,17 @@ short BufferedSerial::poll(short events) const { return revents; } -void BufferedSerial::lock(void) +void UARTSerial::lock(void) { _mutex.lock(); } -void BufferedSerial::unlock(void) +void UARTSerial::unlock(void) { _mutex.unlock(); } -void BufferedSerial::rx_irq(void) +void UARTSerial::rx_irq(void) { bool was_empty = _rxbuf.empty(); @@ -237,7 +237,7 @@ void BufferedSerial::rx_irq(void) } // Also called from write to start transfer -void BufferedSerial::tx_irq(void) +void UARTSerial::tx_irq(void) { bool was_full = _txbuf.full(); diff --git a/drivers/UARTSerial.h b/drivers/UARTSerial.h new file mode 100644 index 0000000000..fda877d896 --- /dev/null +++ b/drivers/UARTSerial.h @@ -0,0 +1,198 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2017 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 MBED_UARTSERIAL_H +#define MBED_UARTSERIAL_H + +#include "platform/platform.h" + +#if DEVICE_SERIAL + +#include "FileHandle.h" +#include "SerialBase.h" +#include "InterruptIn.h" +#include "PlatformMutex.h" +#include "serial_api.h" +#include "CircularBuffer.h" + +#ifndef MBED_CONF_DRIVERS_UART_SERIAL_RXBUF_SIZE +#define MBED_CONF_DRIVERS_UART_SERIAL_RXBUF_SIZE 256 +#endif + +#ifndef MBED_CONF_DRIVERS_UART_SERIAL_TXBUF_SIZE +#define MBED_CONF_DRIVERS_UART_SERIAL_TXBUF_SIZE 256 +#endif + +namespace mbed { + +class UARTSerial : private SerialBase, public FileHandle { + +public: + + /** Create a UARTSerial port, connected to the specified transmit and receive pins, with a particular baud rate. + * @param tx Transmit pin + * @param rx Receive pin + * @param baud The baud rate of the serial port (optional, defaults to MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE) + */ + UARTSerial(PinName tx, PinName rx, int baud = MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE); + virtual ~UARTSerial(); + + /** Equivalent to POSIX poll(). Derived from FileHandle. + * Provides a mechanism to multiplex input/output over a set of file handles. + */ + virtual short poll(short events) const; + + /** Write the contents of a buffer to a file + * + * @param buffer The buffer to write from + * @param size The number of bytes to write + * @return The number of bytes written, negative error on failure + */ + virtual ssize_t write(const void* buffer, size_t length); + + /** Read the contents of a file into a buffer + * + * Follows POSIX semantics: + * + * * if no data is available, and non-blocking set return -EAGAIN + * * if no data is available, and blocking set, wait until data is available + * * If any data is available, call returns immediately + * + * @param buffer The buffer to read in to + * @param size The number of bytes to read + * @return The number of bytes read, 0 at end of file, negative error on failure + */ + virtual ssize_t read(void* buffer, size_t length); + + /** Acquire mutex */ + virtual void lock(void); + + /** Release mutex */ + virtual void unlock(void); + + /** Close a file + * + * @return 0 on success, negative error code on failure + */ + virtual int close(); + + /** Check if the file in an interactive terminal device + * + * @return True if the file is a terminal + * @return False if the file is not a terminal + * @return Negative error code on failure + */ + virtual int isatty(); + + /** Move the file position to a given offset from from a given location + * + * Not valid for a device type FileHandle like UARTSerial. + * In case of UARTSerial, returns ESPIPE + * + * @param offset The offset from whence to move to + * @param whence The start of where to seek + * SEEK_SET to start from beginning of file, + * SEEK_CUR to start from current position in file, + * SEEK_END to start from end of file + * @return The new offset of the file, negative error code on failure + */ + virtual off_t seek(off_t offset, int whence); + + /** Flush any buffers associated with the file + * + * @return 0 on success, negative error code on failure + */ + virtual int sync(); + + /** Set blocking or non-blocking mode + * The default is blocking. + * + * @param blocking true for blocking mode, false for non-blocking mode. + */ + virtual int set_blocking(bool blocking) + { + _blocking = blocking; + return 0; + } + + /** Register a callback on state change of the file. + * + * The specified callback will be called on state changes such as when + * the file can be written to or read from. + * + * The callback may be called in an interrupt context and should not + * perform expensive operations. + * + * Note! This is not intended as an attach-like asynchronous api, but rather + * as a building block for constructing such functionality. + * + * The exact timing of when the registered function + * is called is not guaranteed and susceptible to change. It should be used + * as a cue to make read/write/poll calls to find the current state. + * + * @param func Function to call on state change + */ + virtual void sigio(Callback func); + + /** Setup interrupt handler for DCD line + * + * If DCD line is connected, an IRQ handler will be setup. + * Does nothing if DCD is NC, i.e., not connected. + * + * @param dcd_pin Pin-name for DCD + * @param active_high a boolean set to true if DCD polarity is active low + */ + void set_data_carrier_detect(PinName dcd_pin, bool active_high = false); + +private: + + /** Software serial buffers + * By default buffer size is 256 for TX and 256 for RX. Configurable through mbed_app.json + */ + CircularBuffer _rxbuf; + CircularBuffer _txbuf; + + PlatformMutex _mutex; + + Callback _sigio_cb; + + bool _blocking; + bool _tx_irq_enabled; + InterruptIn *_dcd_irq; + + /** Device Hanged up + * Determines if the device hanged up on us. + * + * @return True, if hanged up + */ + bool hup() const; + + /** ISRs for serial + * Routines to handle interrupts on serial pins. + * Copies data into Circular Buffer. + * Reports the state change to File handle. + */ + void tx_irq(void); + void rx_irq(void); + + void wake(void); + + void dcd_irq(void); +}; +} //namespace mbed + +#endif //DEVICE_SERIAL +#endif //MBED_UARTSERIAL_H diff --git a/drivers/mbed_lib.json b/drivers/mbed_lib.json new file mode 100644 index 0000000000..c268b6381a --- /dev/null +++ b/drivers/mbed_lib.json @@ -0,0 +1,13 @@ +{ + "name": "drivers", + "config": { + "uart-serial-txbuf-size": { + "help": "Default TX buffer size for a UARTSerial instance (unit Bytes))", + "value": 256 + }, + "uart-serial-rxbuf-size": { + "help": "Default RX buffer size for a UARTSerial instance (unit Bytes))", + "value": 256 + } + } +} diff --git a/features/FEATURE_LWIP/lwip-interface/lwip/src/netif/ppp/lwip_utils.c b/features/FEATURE_LWIP/lwip-interface/lwip/src/netif/ppp/lwip_utils.c index 65433e0bf9..d4feebb90b 100644 --- a/features/FEATURE_LWIP/lwip-interface/lwip/src/netif/ppp/lwip_utils.c +++ b/features/FEATURE_LWIP/lwip-interface/lwip/src/netif/ppp/lwip_utils.c @@ -605,11 +605,8 @@ void ppp_print_string(const u_char *p, int len, void (*printer) (void *, const c * ppp_logit - does the hard work for fatal et al. */ static void ppp_logit(int level, const char *fmt, va_list args) { -#ifdef PPP_LOGIT_BUFSIZE - char buf[PPP_LOGIT_BUFSIZE]; -#else - char buf[1024]; -#endif + + char buf[256]; ppp_vslprintf(buf, sizeof(buf), fmt, args); ppp_log_write(level, buf); diff --git a/features/FEATURE_LWIP/lwip-interface/lwipopts.h b/features/FEATURE_LWIP/lwip-interface/lwipopts.h index 37e170d56e..cc2d0b7790 100644 --- a/features/FEATURE_LWIP/lwip-interface/lwipopts.h +++ b/features/FEATURE_LWIP/lwip-interface/lwipopts.h @@ -104,12 +104,12 @@ // Thread stack size for private PPP thread #ifndef MBED_CONF_LWIP_PPP_THREAD_STACKSIZE -#define MBED_CONF_LWIP_PPP_THREAD_STACKSIZE 300 +#define MBED_CONF_LWIP_PPP_THREAD_STACKSIZE 512 #endif #if LWIP_DEBUG #define DEFAULT_THREAD_STACKSIZE MBED_CONF_LWIP_DEFAULT_THREAD_STACKSIZE*2 -#define PPP_THREAD_STACK_SIZE MBED_CONF_LWIP_PPP_THREAD_STACKSIZE*4 +#define PPP_THREAD_STACK_SIZE MBED_CONF_LWIP_PPP_THREAD_STACKSIZE*2 #else #define DEFAULT_THREAD_STACKSIZE MBED_CONF_LWIP_DEFAULT_THREAD_STACKSIZE #define PPP_THREAD_STACK_SIZE MBED_CONF_LWIP_PPP_THREAD_STACKSIZE @@ -265,15 +265,15 @@ #if MBED_CONF_LWIP_ETHERNET_ENABLED #define LWIP_ARP 1 #define LWIP_ETHERNET 1 -#define LWIP_CHECKSUM_ON_COPY 1 #define LWIP_DHCP LWIP_IPV4 #else #define LWIP_ARP 0 #define LWIP_ETHERNET 0 -#define LWIP_CHECKSUM_ON_COPY 0 #endif // MBED_CONF_LWIP_ETHERNET_ENABLED -#if MBED_CONF_LWIP_PPP_ENABLED +// Note generic macro name used rather than MBED_CONF_LWIP_PPP_ENABLED +// to allow users like PPPCellularInterface to detect that nsapi_ppp.h is available. +#if NSAPI_PPP_AVAILABLE #define PPP_SUPPORT 1 #define CHAP_SUPPORT 1 #define PPP_INPROC_IRQ_SAFE 1 @@ -281,7 +281,6 @@ #define PAP_SUPPORT 0 #define VJ_SUPPORT 0 #define PRINTPKT_SUPPORT 0 -#define PPP_LOGIT_BUFSIZE 512 // Broadcast #define IP_SOF_BROADCAST 0 @@ -289,7 +288,7 @@ #define MAXNAMELEN 64 /* max length of hostname or name for auth */ #define MAXSECRETLEN 64 -#endif // MBED_CONF_LWIP_PPP_ENABLED +#endif // NSAPI_PPP_AVAILABLE // Make sure we default these to off, so // LWIP doesn't default to on diff --git a/features/FEATURE_LWIP/lwip-interface/mbed_lib.json b/features/FEATURE_LWIP/lwip-interface/mbed_lib.json index aac5ccd3b0..d330cb8886 100644 --- a/features/FEATURE_LWIP/lwip-interface/mbed_lib.json +++ b/features/FEATURE_LWIP/lwip-interface/mbed_lib.json @@ -27,7 +27,8 @@ }, "ppp-enabled": { "help": "Enable support for PPP interfaces", - "value": false + "value": false, + "macro_name": "NSAPI_PPP_AVAILABLE" }, "use-mbed-trace": { "help": "Use mbed trace for debug, rather than printf", @@ -67,7 +68,7 @@ }, "ppp-thread-stacksize": { "help": "Thread stack size for PPP", - "value": 300 + "value": 512 } } } diff --git a/features/netsocket/CellularBase.h b/features/netsocket/CellularBase.h new file mode 100644 index 0000000000..b1e970c62f --- /dev/null +++ b/features/netsocket/CellularBase.h @@ -0,0 +1,108 @@ +/* Copyright (c) 2017 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 CELLULAR_BASE_H +#define CELLULAR_BASE_H + +#include "netsocket/NetworkInterface.h" + +/** CellularBase class + * + * Common interface that is shared between Cellular interfaces + */ +class CellularBase: public NetworkInterface { + +public: + + /** Set the Cellular network credentials + * + * Please check documentation of connect() for default behaviour of APN settings. + * + * @param apn Access point name + * @param uname optionally, Username + * @param pwd optionally, password + */ + virtual void set_credentials(const char *apn, const char *uname = 0, + const char *pwd = 0) = 0; + + /** Set the pin code for SIM card + * + * @param sim_pin PIN for the SIM card + */ + virtual void set_sim_pin(const char *sim_pin) = 0; + + /** Start the interface + * + * Attempts to connect to a Cellular network. + * + * @param sim_pin PIN for the SIM card + * @param apn optionally, access point name + * @param uname optionally, Username + * @param pwd optionally, password + * @return NSAPI_ERROR_OK on success, or negative error code on failure + */ + virtual nsapi_error_t connect(const char *sim_pin, const char *apn = 0, + const char *uname = 0, + const char *pwd = 0) = 0; + + /** Start the interface + * + * Attempts to connect to a Cellular network. + * If the SIM requires a PIN, and it is not set/invalid, NSAPI_ERROR_AUTH_ERROR is returned. + * + * @return NSAPI_ERROR_OK on success, or negative error code on failure + */ + virtual nsapi_error_t connect() = 0; + + /** Stop the interface + * + * @return 0 on success, or error code on failure + */ + virtual nsapi_error_t disconnect() = 0; + + /** Check if the connection is currently established or not + * + * @return true/false If the cellular module have successfully acquired a carrier and is + * connected to an external packet data network using PPP, isConnected() + * API returns true and false otherwise. + */ + virtual bool is_connected() = 0; + + /** Get the local IP address + * + * @return Null-terminated representation of the local IP address + * or null if no IP address has been received + */ + virtual const char *get_ip_address() = 0; + + /** Get the local network mask + * + * @return Null-terminated representation of the local network mask + * or null if no network mask has been received + */ + virtual const char *get_netmask() = 0; + + /** Get the local gateways + * + * @return Null-terminated representation of the local gateway + * or null if no network mask has been received + */ + virtual const char *get_gateway() = 0; + +}; + +#endif //CELLULAR_BASE_H + +/** @}*/ diff --git a/features/netsocket/CellularInterface.h b/features/netsocket/CellularInterface.h index 833c180ac8..da337992c8 100644 --- a/features/netsocket/CellularInterface.h +++ b/features/netsocket/CellularInterface.h @@ -1,4 +1,7 @@ -/* Copyright (c) 2017 ARM Limited +/** \addtogroup netsocket */ +/** @{*/ +/* CellularInterface + * 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. @@ -18,95 +21,54 @@ #include "netsocket/NetworkInterface.h" + /** CellularInterface class * - * Common interface that is shared between Cellular interfaces + * Common interface that is shared between ethernet hardware */ -class CellularInterface: public NetworkInterface { - +class CellularInterface : public NetworkInterface +{ public: /** CellularInterface lifetime */ - //virtual ~CellularInterface() {}; + virtual ~CellularInterface() {}; - /** Set the Cellular network credentials + /** Set the cellular network APN and credentials * - * Please check documentation of connect() for default behaviour of APN settings. - * - * @param apn Access point name - * @param uname optionally, Username - * @param pwd optionally, password + * @param apn Optional name of the network to connect to + * @param user Optional username for the APN + * @param pass Optional password fot the APN + * @return 0 on success, negative error code on failure */ - virtual void set_credentials(const char *apn, - const char *uname = 0, - const char *pwd = 0) = 0; - - /** Set the pin code for SIM card - * - * @param sim_pin PIN for the SIM card - */ - virtual void set_sim_pin(const char *sim_pin) = 0; + virtual nsapi_error_t set_credentials(const char *apn, + const char *username = 0, const char *password = 0) = 0; /** Start the interface * - * Attempts to connect to a Cellular network. - * - * @param sim_pin PIN for the SIM card - * @param apn optionally, access point name - * @param uname optionally, Username - * @param pwd optionally, password - * @return NSAPI_ERROR_OK on success, or negative error code on failure + * @param apn Optional name of the network to connect to + * @param username Optional username for your APN + * @param password Optional password for your APN + * @return 0 on success, negative error code on failure */ - virtual nsapi_error_t connect(const char *sim_pin, const char *apn = 0, - const char *uname = 0, - const char *pwd = 0) = 0; + virtual nsapi_error_t connect(const char *apn, + const char *username = 0, const char *password = 0) = 0; /** Start the interface * - * Attempts to connect to a Cellular network. - * If the SIM requires a PIN, and it is not set/invalid, NSAPI_ERROR_AUTH_ERROR is returned. + * Attempts to connect to a cellular network based on supplied credentials * - * @return NSAPI_ERROR_OK on success, or negative error code on failure + * @return 0 on success, negative error code on failure */ virtual nsapi_error_t connect() = 0; /** Stop the interface - * - * @return 0 on success, or error code on failure - */ + * + * @return 0 on success, negative error code on failure + */ virtual nsapi_error_t disconnect() = 0; - - /** Check if the connection is currently established or not - * - * @return true/false If the cellular module have successfully acquired a carrier and is - * connected to an external packet data network using PPP, isConnected() - * API returns true and false otherwise. - */ - virtual bool is_connected() = 0; - - /** Get the local IP address - * - * @return Null-terminated representation of the local IP address - * or null if no IP address has been recieved - */ - virtual const char *get_ip_address() = 0; - - /** Get the local network mask - * - * @return Null-terminated representation of the local network mask - * or null if no network mask has been recieved - */ - virtual const char *get_netmask() = 0; - - /** Get the local gateways - * - * @return Null-terminated representation of the local gateway - * or null if no network mask has been recieved - */ - virtual const char *get_gateway() = 0; - }; + #endif /** @}*/ diff --git a/features/netsocket/cellular/generic_modem_driver/OnboardCellularInterface.cpp b/features/netsocket/cellular/generic_modem_driver/OnboardCellularInterface.cpp new file mode 100644 index 0000000000..6c823a383b --- /dev/null +++ b/features/netsocket/cellular/generic_modem_driver/OnboardCellularInterface.cpp @@ -0,0 +1,54 @@ +/* Copyright (c) 2017 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. + */ +#include "OnboardCellularInterface.h" + +#if MODEM_ON_BOARD && MODEM_ON_BOARD_UART && NSAPI_PPP_AVAILABLE + +#include "onboard_modem_api.h" + +/** + * OnboardCellularInterface is an on-board specific implementation. + */ +OnboardCellularInterface::OnboardCellularInterface(bool debug) : + UARTCellularInterface(MDMTXD, MDMRXD, MDMDCD, MDMRTS, + MDMCTS, MDMRI, MDMDTR, MDMDSR, + MBED_CONF_PPP_CELL_IFACE_BAUD_RATE, MDM_PIN_POLARITY, debug) +{ +} + +OnboardCellularInterface::~OnboardCellularInterface() +{ +} + +void OnboardCellularInterface::modem_init() +{ + ::onboard_modem_init(); +} + +void OnboardCellularInterface::modem_deinit() +{ + ::onboard_modem_deinit(); +} + +void OnboardCellularInterface::modem_power_up() +{ + ::onboard_modem_power_up(); +} + +void OnboardCellularInterface::modem_power_down() +{ + ::onboard_modem_power_down(); +} +#endif diff --git a/features/netsocket/cellular/generic_modem_driver/OnboardCellularInterface.h b/features/netsocket/cellular/generic_modem_driver/OnboardCellularInterface.h new file mode 100644 index 0000000000..1adc085e74 --- /dev/null +++ b/features/netsocket/cellular/generic_modem_driver/OnboardCellularInterface.h @@ -0,0 +1,73 @@ +/* Copyright (c) 2017 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 ONBOARD_CELLULAR_INTERFACE_ +#define ONBOARD_CELLULAR_INTERFACE_ + +#if MODEM_ON_BOARD && MODEM_ON_BOARD_UART && NSAPI_PPP_AVAILABLE + +#include "UARTCellularInterface.h" + +/** OnboardCellularInterface class + * + * This interface serves as the controller/driver for an + * onboard modem implementing onboard_modem_api.h. + * + * Depending on the type of on-board modem, OnboardCellularInterface + * could be derived from different implementation classes. + * Portable applications should only rely on it being a CellularBase. + */ +class OnboardCellularInterface : public UARTCellularInterface { + +public: + + OnboardCellularInterface(bool debug = false); + + virtual ~OnboardCellularInterface(); + +protected: + /** Sets the modem up for powering on + * + * modem_init() is equivalent to plugging in the device, e.g., attaching power and serial port. + * Uses onboard_modem_api.h where the implementation of onboard_modem_api is provided by the target. + */ + virtual void modem_init(); + + /** Sets the modem in unplugged state + * + * modem_deinit() will be equivalent to pulling the plug off of the device, i.e., detaching power + * and serial port. This puts the modem in lowest power state. + * Uses onboard_modem_api.h where the implementation of onboard_modem_api is provided by the target. + */ + virtual void modem_deinit(); + + /** Powers up the modem + * + * modem_power_up() is equivalent to pressing the soft power button. + * The driver may repeat this if the modem is not responsive to AT commands. + * Uses onboard_modem_api.h where the implementation of onboard_modem_api is provided by the target. + */ + virtual void modem_power_up(); + + /** Powers down the modem + * + * modem_power_down() is equivalent to turning off the modem by button press. + * Uses onboard_modem_api.h where the implementation of onboard_modem_api is provided by the target. + */ + virtual void modem_power_down(); +}; + +#endif //MODEM_ON_BOARD && MODEM_ON_BOARD_UART && NSAPI_PPP_AVAILABLE +#endif //ONBOARD_CELLULAR_INTERFACE_ diff --git a/features/cellular/TARGET_GENERIC_MODEM/generic_modem_driver/ReferenceCellularDriver.cpp b/features/netsocket/cellular/generic_modem_driver/PPPCellularInterface.cpp similarity index 68% rename from features/cellular/TARGET_GENERIC_MODEM/generic_modem_driver/ReferenceCellularDriver.cpp rename to features/netsocket/cellular/generic_modem_driver/PPPCellularInterface.cpp index 7c192dd9b5..c2c1dc9e7f 100644 --- a/features/cellular/TARGET_GENERIC_MODEM/generic_modem_driver/ReferenceCellularDriver.cpp +++ b/features/netsocket/cellular/generic_modem_driver/PPPCellularInterface.cpp @@ -12,15 +12,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "ReferenceCellularDriver.h" +#include "PPPCellularInterface.h" + +#if NSAPI_PPP_AVAILABLE #include -#include "modem_api.h" -#include "platform/BufferedSerial.h" #include "nsapi_ppp.h" -#if MBED_CONF_REF_CELL_DRV_APN_LOOKUP -#include "APN_db.h" -#endif //MBED_CONF_REF_CELL_DRV_APN_LOOKUP +#if MBED_CONF_PPP_CELL_IFACE_APN_LOOKUP +#include "utils/APN_db.h" +#endif //MBED_CONF_PPP_CELL_IFACE_APN_LOOKUP #if defined(FEATURE_COMMON_PAL) #include "mbed_trace.h" #define TRACE_GROUP "UCID" @@ -30,8 +30,6 @@ #define tr_error(...) (void(0)) //dummies if feature common pal is not added #endif //defined(FEATURE_COMMON_PAL) -#define BAUD_RATE 115200 - /** * PDP (packet data profile) Context */ @@ -42,31 +40,30 @@ */ #define OUTPUT_ENTER_KEY "\r" -#if MBED_CONF_REF_CELL_DRV_AT_PARSER_BUFFER_SIZE -#define AT_PARSER_BUFFER_SIZE MBED_CONF_REF_CELL_DRV_AT_PARSER_BUFFER_SIZE //bytes +#if MBED_CONF_PPP_CELL_IFACE_AT_PARSER_BUFFER_SIZE +#define AT_PARSER_BUFFER_SIZE MBED_CONF_PPP_CELL_IFACE_AT_PARSER_BUFFER_SIZE //bytes #else #define AT_PARSER_BUFFER_SIZE 256 //bytes -#endif //MMBED_CONF_REF_CELL_DRV_AT_PARSER_BUFFER_SIZE +#endif //MBED_CONF_PPP_CELL_IFACE_AT_PARSER_BUFFER_SIZE -#if MBED_CONF_REF_CELL_DRV_AT_PARSER_TIMEOUT -#define AT_PARSER_TIMEOUT MBED_CONF_REF_CELL_DRV_AT_PARSER_TIMEOUT +#if MBED_CONF_PPP_CELL_IFACE_AT_PARSER_TIMEOUT +#define AT_PARSER_TIMEOUT MBED_CONF_PPP_CELL_IFACE_AT_PARSER_TIMEOUT #else #define AT_PARSER_TIMEOUT 8*1000 //miliseconds -#endif //MBED_CONF_REF_CELL_DRV_AT_PARSER_TIMEOUT +#endif //MBED_CONF_PPP_CELL_IFACE_AT_PARSER_TIMEOUT static bool initialized; static bool set_credentials_api_used; static bool set_sim_pin_check_request; static bool change_pin; static device_info dev_info; -static modem_t mdm_object; -static void parser_abort(ATParser *at) +static void parser_abort(ATCmdParser *at) { at->abort(); } -static bool get_CCID(ATParser *at) +static bool get_CCID(ATCmdParser *at) { // Returns the ICCID (Integrated Circuit Card ID) of the SIM-card. // ICCID is a serial number identifying the SIM. @@ -75,7 +72,7 @@ static bool get_CCID(ATParser *at) return success; } -static bool get_IMSI(ATParser *at) +static bool get_IMSI(ATCmdParser *at) { // International mobile subscriber identification bool success = at->send("AT+CIMI") && at->recv("%15[^\n]\nOK\n", dev_info.imsi); @@ -83,7 +80,7 @@ static bool get_IMSI(ATParser *at) return success; } -static bool get_IMEI(ATParser *at) +static bool get_IMEI(ATCmdParser *at) { // International mobile equipment identifier bool success = at->send("AT+CGSN") && at->recv("%15[^\n]\nOK\n", dev_info.imei); @@ -91,7 +88,7 @@ static bool get_IMEI(ATParser *at) return success; } -static bool get_MEID(ATParser *at) +static bool get_MEID(ATCmdParser *at) { // Mobile equipment identifier bool success = at->send("AT+GSN") @@ -100,7 +97,7 @@ static bool get_MEID(ATParser *at) return success; } -static bool set_CMGF(ATParser *at) +static bool set_CMGF(ATCmdParser *at) { // Preferred message format // set AT+CMGF=[mode] , 0 PDU mode, 1 text mode @@ -108,7 +105,7 @@ static bool set_CMGF(ATParser *at) return success; } -static bool set_CNMI(ATParser *at) +static bool set_CNMI(ATCmdParser *at) { // New SMS indication configuration // set AT+CMTI=[mode, index] , 0 PDU mode, 1 text mode @@ -117,7 +114,7 @@ static bool set_CNMI(ATParser *at) return success; } -static void CMTI_URC(ATParser *at) +static void CMTI_URC(ATCmdParser *at) { // our CMGF = 1, i.e., text mode. So we expect response in this format: //+CMTI: ,, @@ -126,7 +123,7 @@ static void CMTI_URC(ATParser *at) } -static void CMT_URC(ATParser *at) +static void CMT_URC(ATCmdParser *at) { // our CMGF = 1, i.e., text mode. So we expect response in this format: //+CMT: ,[],[,, @@ -142,7 +139,7 @@ static void CMT_URC(ATParser *at) } -static bool set_atd(ATParser *at) +static bool set_atd(ATCmdParser *at) { bool success = at->send("ATD*99***"CTX"#") && at->recv("CONNECT"); @@ -152,7 +149,7 @@ static bool set_atd(ATParser *at) /** * Enables or disables SIM pin check lock */ -static nsapi_error_t do_sim_pin_check(ATParser *at, const char *pin) +static nsapi_error_t do_sim_pin_check(ATCmdParser *at, const char *pin) { bool success; if (set_sim_pin_check_request) { @@ -171,7 +168,7 @@ static nsapi_error_t do_sim_pin_check(ATParser *at, const char *pin) /** * Change the pin code for the SIM card */ -static nsapi_error_t do_change_sim_pin(ATParser *at, const char *old_pin, const char *new_pin) +static nsapi_error_t do_change_sim_pin(ATCmdParser *at, const char *old_pin, const char *new_pin) { /* changes the SIM pin */ bool success = at->send("AT+CPWD=\"SC\",\"%s\",\"%s\"", old_pin, new_pin) && at->recv("OK"); @@ -255,43 +252,58 @@ static bool is_registered_psd() (dev_info.reg_status_psd == PSD_REGISTERED_ROAMING); } -ReferenceCellularDriver::ReferenceCellularDriver(PinName tx, PinName rx, int baud, bool debugOn) +PPPCellularInterface::PPPCellularInterface(FileHandle *fh, bool debug) { _new_pin = NULL; _pin = NULL; _at = NULL; - _dcd = NULL; _apn = "internet"; _uname = NULL; _pwd = NULL; - _debug_trace_on = false; - - // Set up File Handle - _fh = new BufferedSerial(tx, rx, BAUD_RATE); - - if (debugOn) { - _debug_trace_on = true; - } - + _fh = fh; + _debug_trace_on = debug; dev_info.reg_status_csd = CSD_NOT_REGISTERED_NOT_SEARCHING; dev_info.reg_status_psd = PSD_NOT_REGISTERED_NOT_SEARCHING; dev_info.ppp_connection_up = false; - } -ReferenceCellularDriver::~ReferenceCellularDriver() + +PPPCellularInterface::~PPPCellularInterface() { - delete _fh; delete _at; - delete _dcd; } -void ReferenceCellularDriver::modem_debug_on(bool on) +void PPPCellularInterface::enable_hup(bool) +{ + //meant to be overridden +} + +void PPPCellularInterface::modem_init() +{ + //meant to be overridden +} + +void PPPCellularInterface::modem_deinit() +{ + //meant to be overridden +} + +void PPPCellularInterface::modem_power_up() +{ + //meant to be overridden +} + +void PPPCellularInterface::modem_power_down() +{ + //meant to be overridden +} + +void PPPCellularInterface::modem_debug_on(bool on) { _debug_trace_on = on; } -void ReferenceCellularDriver::connection_status_cb(Callback cb) +void PPPCellularInterface::connection_status_cb(Callback cb) { _connection_status_cb = cb; } @@ -300,7 +312,7 @@ void ReferenceCellularDriver::connection_status_cb(Callback * Public API. Sets up the flag for the driver to enable or disable SIM pin check * at the next boot. */ -void ReferenceCellularDriver::set_sim_pin_check(bool check) +void PPPCellularInterface::set_sim_pin_check(bool check) { set_sim_pin_check_request = check; } @@ -308,13 +320,13 @@ void ReferenceCellularDriver::set_sim_pin_check(bool check) /** * Public API. Sets up the flag for the driver to change pin code for SIM card */ -void ReferenceCellularDriver::set_new_sim_pin(const char *new_pin) +void PPPCellularInterface::set_new_sim_pin(const char *new_pin) { change_pin = true; _new_pin = new_pin; } -bool ReferenceCellularDriver::nwk_registration(uint8_t nwk_type) +bool PPPCellularInterface::nwk_registration(uint8_t nwk_type) { bool success = false; bool registered = false; @@ -383,13 +395,13 @@ bool ReferenceCellularDriver::nwk_registration(uint8_t nwk_type) return registered; } -bool ReferenceCellularDriver::is_connected() +bool PPPCellularInterface::is_connected() { return dev_info.ppp_connection_up; } // Get the SIM card going. -nsapi_error_t ReferenceCellularDriver::initialize_sim_card() +nsapi_error_t PPPCellularInterface::initialize_sim_card() { nsapi_error_t nsapi_error = NSAPI_ERROR_AUTH_FAILURE; int retry_count = 0; @@ -426,12 +438,12 @@ nsapi_error_t ReferenceCellularDriver::initialize_sim_card() return nsapi_error; } -void ReferenceCellularDriver::set_sim_pin(const char *pin) { +void PPPCellularInterface::set_sim_pin(const char *pin) { /* overwrite the default pin by user provided pin */ _pin = pin; } -nsapi_error_t ReferenceCellularDriver::setup_context_and_credentials() +nsapi_error_t PPPCellularInterface::setup_context_and_credentials() { bool success; @@ -463,7 +475,7 @@ retry_without_ipv6: } -void ReferenceCellularDriver::set_credentials(const char *apn, const char *uname, +void PPPCellularInterface::set_credentials(const char *apn, const char *uname, const char *pwd) { _apn = apn; @@ -474,13 +486,13 @@ void ReferenceCellularDriver::set_credentials(const char *apn, const char *unam -void ReferenceCellularDriver::setup_at_parser() +void PPPCellularInterface::setup_at_parser() { if (_at) { return; } - _at = new ATParser(_fh, OUTPUT_ENTER_KEY, AT_PARSER_BUFFER_SIZE, AT_PARSER_TIMEOUT, + _at = new ATCmdParser(_fh, OUTPUT_ENTER_KEY, AT_PARSER_BUFFER_SIZE, AT_PARSER_TIMEOUT, _debug_trace_on ? true : false); /* Error cases, out of band handling */ @@ -494,13 +506,13 @@ void ReferenceCellularDriver::setup_at_parser() _at->oob("+CMTI", callback(CMTI_URC, _at)); } -void ReferenceCellularDriver::shutdown_at_parser() +void PPPCellularInterface::shutdown_at_parser() { delete _at; _at = NULL; } -nsapi_error_t ReferenceCellularDriver::connect(const char *sim_pin, const char *apn, const char *uname, const char *pwd) +nsapi_error_t PPPCellularInterface::connect(const char *sim_pin, const char *apn, const char *uname, const char *pwd) { if (!sim_pin) { return NSAPI_ERROR_PARAMETER; @@ -523,7 +535,7 @@ nsapi_error_t ReferenceCellularDriver::connect(const char *sim_pin, const char * return connect(); } -nsapi_error_t ReferenceCellularDriver::connect() +nsapi_error_t PPPCellularInterface::connect() { nsapi_error_t retcode; bool success; @@ -533,141 +545,131 @@ nsapi_error_t ReferenceCellularDriver::connect() return NSAPI_ERROR_IS_CONNECTED; } -#if MBED_CONF_REF_CELL_DRV_APN_LOOKUP && !set_credentials_api_used - const char *apn_config; - do { -#endif - -retry_init: - - /* setup AT parser */ - setup_at_parser(); - - if (!initialized) { - - /* If we are using serial interface, we want to make sure that DCD line is - * not connected as long as we are using ATParser. - * As soon as we get into data mode, we would like to attach an interrupt line - * to DCD line. - * Here, we detach the line */ - BufferedSerial *serial = static_cast(_fh); - serial->set_data_carrier_detect(NC); - - - if (!power_up_modem()) { - return NSAPI_ERROR_DEVICE_ERROR; - } - - retcode = initialize_sim_card(); - if (retcode != NSAPI_ERROR_OK) { - return retcode; - } - - success = nwk_registration(PACKET_SWITCHED) //perform network registration - && get_CCID(_at) //get integrated circuit ID of the SIM - && get_IMSI(_at) //get international mobile subscriber information - && get_IMEI(_at) //get international mobile equipment identifier - && get_MEID(_at) //its same as IMEI - && set_CMGF(_at) //set message format for SMS - && set_CNMI(_at); //set new SMS indication - - if (!success) { - return NSAPI_ERROR_NO_CONNECTION; - } - - /* Check if user want skip SIM pin checking on boot up */ - if (set_sim_pin_check_request) { - retcode = do_sim_pin_check(_at, _pin); - if (retcode != NSAPI_ERROR_OK) { - return retcode; - } - /* set this request to false, as it is unnecessary to repeat in case of retry */ - set_sim_pin_check_request = false; - } - - /* check if the user requested a sim pin change */ - if (change_pin) { - retcode = do_change_sim_pin(_at, _pin, _new_pin); - if (retcode != NSAPI_ERROR_OK) { - return retcode; - } - /* set this request to false, as it is unnecessary to repeat in case of retry */ - change_pin = false; - } - -#if MBED_CONF_REF_CELL_DRV_APN_LOOKUP && !set_credentials_api_used + const char *apn_config = NULL; +#if MBED_CONF_PPP_CELL_IFACE_APN_LOOKUP + if (!set_credentials_api_used) { apn_config = apnconfig(dev_info.imsi); - if (apn_config) { - _apn = _APN_GET(apn_config); - _uname = _APN_GET(apn_config); - _pwd = _APN_GET(apn_config); - } - - _apn = _apn ? _apn : NULL; - _uname = _uname ? _uname : NULL; - _pwd = _pwd ? _pwd : NULL; + } #endif - //sets up APN and IP protocol for external PDP context - retcode = setup_context_and_credentials(); - if (retcode != NSAPI_ERROR_OK) { - return retcode; + do { + retry_init: + + /* setup AT parser */ + setup_at_parser(); + + if (!initialized) { + + /* If we have hangup (eg DCD) detection, we don't want it active + * as long as we are using ATCmdParser. + * As soon as we get into data mode, we will turn it back on. */ + enable_hup(false); + + if (!power_up()) { + return NSAPI_ERROR_DEVICE_ERROR; + } + + retcode = initialize_sim_card(); + if (retcode != NSAPI_ERROR_OK) { + return retcode; + } + + success = nwk_registration(PACKET_SWITCHED) //perform network registration + && get_CCID(_at)//get integrated circuit ID of the SIM + && get_IMSI(_at)//get international mobile subscriber information + && get_IMEI(_at)//get international mobile equipment identifier + && get_MEID(_at)//its same as IMEI + && set_CMGF(_at)//set message format for SMS + && set_CNMI(_at);//set new SMS indication + + if (!success) { + return NSAPI_ERROR_NO_CONNECTION; + } + + /* Check if user want skip SIM pin checking on boot up */ + if (set_sim_pin_check_request) { + retcode = do_sim_pin_check(_at, _pin); + if (retcode != NSAPI_ERROR_OK) { + return retcode; + } + /* set this request to false, as it is unnecessary to repeat in case of retry */ + set_sim_pin_check_request = false; + } + + /* check if the user requested a sim pin change */ + if (change_pin) { + retcode = do_change_sim_pin(_at, _pin, _new_pin); + if (retcode != NSAPI_ERROR_OK) { + return retcode; + } + /* set this request to false, as it is unnecessary to repeat in case of retry */ + change_pin = false; + } + +#if MBED_CONF_PPP_CELL_IFACE_APN_LOOKUP + if (apn_config) { + _apn = _APN_GET(apn_config); + _uname = _APN_GET(apn_config); + _pwd = _APN_GET(apn_config); + } +#endif + + //sets up APN and IP protocol for external PDP context + retcode = setup_context_and_credentials(); + if (retcode != NSAPI_ERROR_OK) { + return retcode; + } + + if (!success) { + shutdown_at_parser(); + return NSAPI_ERROR_NO_CONNECTION; + } + + initialized = true; + did_init = true; + } else { + /* If we were already initialized, we expect to receive NO_CARRIER response + * from the modem as we were kicked out of Data mode */ + _at->recv("NO CARRIER"); + success = _at->send("AT") && _at->recv("OK"); } + /* Attempt to enter data mode */ + success = set_atd(_at); //enter into Data mode with the modem if (!success) { + power_down(); + initialized = false; + + /* if we were previously initialized , i.e., not in this particular attempt, + * we want to re-initialize */ + if (!did_init) { + goto retry_init; + } + + /* shutdown AT parser before notifying application of the failure */ shutdown_at_parser(); + return NSAPI_ERROR_NO_CONNECTION; } - initialized = true; - did_init = true; - } else { - /* If we were already initialized, we expect to receive NO_CARRIER response - * from the modem as we were kicked out of Data mode */ - _at->recv("NO CARRIER"); - success = _at->send("AT") && _at->recv("OK"); - } - - /* Attempt to enter data mode */ - success = set_atd(_at); //enter into Data mode with the modem - if (!success) { - power_down_modem(); - initialized = false; - - /* if we were previously initialized , i.e., not in this particular attempt, - * we want to re-initialize */ - if (!did_init) { - goto retry_init; - } - - /* shutdown AT parser before notifying application of the failure */ + /* This is the success case. + * Save RAM, discard AT Parser as we have entered Data mode. */ shutdown_at_parser(); - return NSAPI_ERROR_NO_CONNECTION; - } + /* We now want hangup (e.g., DCD) detection if available */ + enable_hup(true); - /* This is the success case. - * Save RAM, discard AT Parser as we have entered Data mode. */ - shutdown_at_parser(); + /* Initialize PPP + * mbed_ppp_init() is a blocking call, it will block until + * connected, or timeout after 30 seconds*/ + retcode = nsapi_ppp_connect(_fh, _connection_status_cb, _uname, _pwd); + if (retcode == NSAPI_ERROR_OK) { + dev_info.ppp_connection_up = true; + } - /* Here we would like to attach an interrupt line to DCD pin - * We cast back the serial interface from the file handle and set - * the DCD line. */ - BufferedSerial *serial = static_cast(_fh); - serial->set_data_carrier_detect(MDMDCD, MDMDCD_POLARITY); + }while(!dev_info.ppp_connection_up && apn_config && *apn_config); - /* Initialize PPP - * mbed_ppp_init() is a blocking call, it will block until - * connected, or timeout after 30 seconds*/ - retcode = nsapi_ppp_connect(_fh, _connection_status_cb, _uname, _pwd); - if (retcode == NSAPI_ERROR_OK) { - dev_info.ppp_connection_up = true; - } - -#if MBED_CONF_REF_CELL_DRV_APN_LOOKUP && !set_credentials_api_used - } while(!dev_info.ppp_connection_up && apn_config && *apn_config); -#endif - return retcode; + return retcode; } /** @@ -676,7 +678,7 @@ retry_init: * Disconnects from PPP connection only and brings down the underlying network * interface */ -nsapi_error_t ReferenceCellularDriver::disconnect() +nsapi_error_t PPPCellularInterface::disconnect() { nsapi_error_t ret = nsapi_ppp_disconnect(_fh); if (ret == NSAPI_ERROR_OK) { @@ -687,27 +689,27 @@ nsapi_error_t ReferenceCellularDriver::disconnect() return ret; } -const char *ReferenceCellularDriver::get_ip_address() +const char *PPPCellularInterface::get_ip_address() { return nsapi_ppp_get_ip_addr(_fh); } -const char *ReferenceCellularDriver::get_netmask() +const char *PPPCellularInterface::get_netmask() { return nsapi_ppp_get_netmask(_fh); } -const char *ReferenceCellularDriver::get_gateway() +const char *PPPCellularInterface::get_gateway() { return nsapi_ppp_get_ip_addr(_fh); } /** Power down modem * Uses AT command to do it */ -void ReferenceCellularDriver::power_down_modem() +void PPPCellularInterface::power_down() { - modem_power_down(&mdm_object); - modem_deinit(&mdm_object); + modem_power_down(); + modem_deinit(); } /** @@ -715,10 +717,10 @@ void ReferenceCellularDriver::power_down_modem() * * Enables the GPIO lines to the modem and then wriggles the power line in short pulses. */ -bool ReferenceCellularDriver::power_up_modem() +bool PPPCellularInterface::power_up() { /* Initialize GPIO lines */ - modem_init(&mdm_object); + modem_init(); /* Give modem a little time to settle down */ wait(0.25); @@ -726,7 +728,7 @@ bool ReferenceCellularDriver::power_up_modem() int retry_count = 0; while (true) { - modem_power_up(&mdm_object); + modem_power_up(); /* Modem tends to spit out noise during power up - don't confuse the parser */ _at->flush(); /* It is mandatory to avoid sending data to the serial port during the first 200 ms @@ -771,8 +773,9 @@ failure: /** * Get a pointer to the underlying network stack */ -NetworkStack *ReferenceCellularDriver::get_stack() +NetworkStack *PPPCellularInterface::get_stack() { return nsapi_ppp_get_stack(); } +#endif // NSAPI_PPP_AVAILABLE diff --git a/features/cellular/TARGET_GENERIC_MODEM/generic_modem_driver/ReferenceCellularDriver.h b/features/netsocket/cellular/generic_modem_driver/PPPCellularInterface.h similarity index 71% rename from features/cellular/TARGET_GENERIC_MODEM/generic_modem_driver/ReferenceCellularDriver.h rename to features/netsocket/cellular/generic_modem_driver/PPPCellularInterface.h index 2c91948e46..7920cd8c3f 100644 --- a/features/cellular/TARGET_GENERIC_MODEM/generic_modem_driver/ReferenceCellularDriver.h +++ b/features/netsocket/cellular/generic_modem_driver/PPPCellularInterface.h @@ -13,16 +13,14 @@ * limitations under the License. */ -#ifndef REFERENCE_CELLULAR_DRIVER_ -#define REFERENCE_CELLULAR_DRIVER_ +#ifndef PPP_CELLULAR_INTERFACE_ +#define PPP_CELLULAR_INTERFACE_ +#include "CellularBase.h" +#include "platform/ATCmdParser.h" #include "mbed.h" -#include "nsapi.h" -#include "rtos.h" -#include "FileHandle.h" -#include "InterruptIn.h" -#include "ATParser.h" -#include "PinNames.h" + +#if NSAPI_PPP_AVAILABLE // Forward declaration class NetworkStack; @@ -93,16 +91,27 @@ typedef struct { nwk_registration_status_psd reg_status_psd; } device_info; -/** ReferenceCellularDriver class +/** PPPCellularInterface class * * This interface serves as the controller/driver for the Cellular * modems (tested with UBLOX_C027 and MTS_DRAGONFLY_F411RE). + * + * The driver will work with any generic FileHandle, and can be + * derived from in order to provide forms for specific interfaces, as well as + * adding extra power and reset controls alongside the FileHandle. */ -class ReferenceCellularDriver : public CellularInterface { +class PPPCellularInterface : public CellularBase { public: - ReferenceCellularDriver(PinName tx = MDMTXD, PinName rx = MDMRXD, int baud = MBED_CONF_REF_CELL_DRV_BAUD_RATE, bool debugOn = false); - ~ReferenceCellularDriver(); + + /** Constructor for a generic modem, using a single FileHandle for commands and PPP data. + * + * The file handle pointer is not accessed within the constructor, only recorded for later + * use - this permits a derived class to pass a pointer to a not-yet-constructed member object. + */ + PPPCellularInterface(FileHandle *fh, bool debug = false); + + virtual ~PPPCellularInterface(); /** Set the Cellular network credentials * @@ -139,7 +148,6 @@ public: virtual nsapi_error_t connect(const char *sim_pin, const char *apn = 0, const char *uname = 0, const char *pwd = 0); - /** Attempt to connect to the Cellular network * * Brings up the network interface. Connects to the Cellular Radio @@ -148,12 +156,12 @@ public: * * If the SIM requires a PIN, and it is not set/invalid, NSAPI_ERROR_AUTH_ERROR is returned. * For APN setup, default behaviour is to use 'internet' as APN string and assuming no authentication - * is required, i.e., username and password are no set. Optionally, a database lookup can be requested - * by turning on the APN database lookup feature. In order to do so, add 'MBED_REF_CELL_DRV_APN_LOOKUP' + * is required, i.e., username and password are not set. Optionally, a database lookup can be requested + * by turning on the APN database lookup feature. In order to do so, add 'MBED_CONF_PPP_CELL_IFACE_APN_LOOKUP' * in your mbed_app.json. APN database is by no means exhaustive. It contains a short list of some public * APNs with publicly available usernames and passwords (if required) in some particular countries only. * Lookup is done using IMSI (International mobile subscriber identifier). - * Please note that even if 'MBED_REF_CELL_DRV_APN_LOOKUP' config option is set, 'set_credentials()' api still + * Please note that even if 'MBED_CONF_PPP_CELL_IFACE_APN_LOOKUP' config option is set, 'set_credentials()' api still * gets the precedence. If the aforementioned API is not used and the config option is set but no match is found in * the lookup table then the driver tries to resort to default APN settings. * @@ -237,8 +245,7 @@ public: private: FileHandle *_fh; - ATParser *_at; - InterruptIn *_dcd; + ATCmdParser *_at; const char *_new_pin; const char *_pin; const char *_apn; @@ -246,14 +253,72 @@ private: const char *_pwd; bool _debug_trace_on; Callback _connection_status_cb; + void base_initialization(); void setup_at_parser(); void shutdown_at_parser(); nsapi_error_t initialize_sim_card(); nsapi_error_t setup_context_and_credentials(); - bool power_up_modem(); - void power_down_modem(); + bool power_up(); + void power_down(); protected: + /** Enable or disable hang-up detection + * + * When in PPP data pump mode, it is helpful if the FileHandle will signal hang-up via + * POLLHUP, e.g., if the DCD line is deasserted on a UART. During command mode, this + * signaling is not desired. enable_hup() controls whether this function should be + * active. + * + * Meant to be overridden. + */ + virtual void enable_hup(bool enable); + + /** Sets the modem up for powering on + * + * modem_init() is equivalent to plugging in the device, e.g., attaching power and serial port. + * It is meant to be overridden. + * If the modem is on-board, an implementation of onboard_modem_api.h + * will override this. + * If the the modem is a plugged-in device (i.e., a shield type component), the driver deriving from this + * class will override. + */ + virtual void modem_init(); + + /** Sets the modem in unplugged state + * + * modem_deinit() will be equivalent to pulling the plug off of the device, i.e., detaching power + * and serial port. This puts the modem in lowest power state. + * It is meant to be overridden. + * If the modem is on-board, an implementation of onboard_modem_api.h + * will override this. + * If the the modem is a plugged-in device (i.e., a shield type component), the driver deriving from this + * class will override. + */ + virtual void modem_deinit(); + + /** Powers up the modem + * + * modem_power_up() is equivalent to pressing the soft power button. + * The driver may repeat this if the modem is not responsive to AT commands. + * It is meant to be overridden. + * If the modem is on-board, an implementation of onboard_modem_api.h + * will override this. + * If the the modem is a plugged-in device (i.e., a shield type component), the driver deriving from this + * class will override. + */ + virtual void modem_power_up(); + + /** Powers down the modem + * + * modem_power_down() is equivalent to turning off the modem by button press. + * It is meant to be overridden. + * If the modem is on-board, an implementation of onboard_modem_api.h + * will override this. + * If the the modem is a plugged-in device (i.e., a shield type component), the driver deriving from this + * class will override. + */ + virtual void modem_power_down(); + /** Provide access to the underlying stack * * @return The underlying network stack @@ -274,4 +339,6 @@ protected: }; -#endif //REFERENCE_CELLULAR_DRIVER_ +#endif //NSAPI_PPP_AVAILABLE + +#endif //PPP_CELLULAR_INTERFACE_ diff --git a/features/netsocket/cellular/generic_modem_driver/UARTCellularInterface.cpp b/features/netsocket/cellular/generic_modem_driver/UARTCellularInterface.cpp new file mode 100644 index 0000000000..e1ee638876 --- /dev/null +++ b/features/netsocket/cellular/generic_modem_driver/UARTCellularInterface.cpp @@ -0,0 +1,38 @@ +/* Copyright (c) 2017 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. + */ +#include "UARTCellularInterface.h" + +#if NSAPI_PPP_AVAILABLE + +UARTCellularInterface::UARTCellularInterface(PinName txd, PinName rxd, PinName dcd, PinName rts, PinName cts, PinName ri, + PinName dtr, PinName dsr, int baud, bool active_high, bool debug) : + PPPCellularInterface(&_serial, debug), + _serial(txd, rxd, baud) +{ + _dcd_pin = dcd; + _active_high = active_high; +} + +UARTCellularInterface::~UARTCellularInterface() +{ + //do nothing +} + +void UARTCellularInterface::enable_hup(bool enable) +{ + _serial.set_data_carrier_detect(enable ? _dcd_pin : NC, _active_high); +} + +#endif // NSAPI_PPP_AVAILABLE diff --git a/features/netsocket/cellular/generic_modem_driver/UARTCellularInterface.h b/features/netsocket/cellular/generic_modem_driver/UARTCellularInterface.h new file mode 100644 index 0000000000..e86d5862c6 --- /dev/null +++ b/features/netsocket/cellular/generic_modem_driver/UARTCellularInterface.h @@ -0,0 +1,61 @@ +/* Copyright (c) 2017 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 UART_CELLULAR_INTERFACE_ +#define UART_CELLULAR_INTERFACE_ + +#include "PPPCellularInterface.h" +#include "UARTSerial.h" + +#if NSAPI_PPP_AVAILABLE + +/** UARTCellularInterface class + * + * This interface serves as the controller/driver for Cellular + * modems attached via a UART (tested with UBLOX_C027 and MTS_DRAGONFLY_F411RE). + * + * It constructs a FileHandle and passes it back to its base class as well as overrides + * enable_hup() in the base class. + */ +class UARTCellularInterface : public PPPCellularInterface { + +public: + + UARTCellularInterface(PinName tx, PinName rx, PinName dcd = NC, PinName rts = NC, PinName cts = NC, PinName ri = NC, + PinName dtr = NC, PinName dsr = NC, int baud = MBED_CONF_PPP_CELL_IFACE_BAUD_RATE, + bool active_high = false, + bool debug = false); + + virtual ~UARTCellularInterface(); + +private: + UARTSerial _serial; + PinName _dcd_pin; + bool _active_high; + +protected: + /** Enable or disable hang-up detection + * + * When in PPP data pump mode, it is helpful if the FileHandle will signal hang-up via + * POLLHUP, e.g., if the DCD line is deasserted on a UART. During command mode, this + * signaling is not desired. enable_hup() controls whether this function should be + * active. + */ + virtual void enable_hup(bool enable); +}; + +#endif //NSAPI_PPP_AVAILABLE + +#endif //UART_CELLULAR_INTERFACE_ diff --git a/features/cellular/TARGET_GENERIC_MODEM/generic_modem_driver/mbed_lib.json b/features/netsocket/cellular/generic_modem_driver/mbed_lib.json similarity index 54% rename from features/cellular/TARGET_GENERIC_MODEM/generic_modem_driver/mbed_lib.json rename to features/netsocket/cellular/generic_modem_driver/mbed_lib.json index 4563311c44..267aee66e2 100644 --- a/features/cellular/TARGET_GENERIC_MODEM/generic_modem_driver/mbed_lib.json +++ b/features/netsocket/cellular/generic_modem_driver/mbed_lib.json @@ -1,14 +1,9 @@ { - "name": "ref-cell-drv", + "name": "ppp-cell-iface", "config": { "baud-rate": 115200, "apn-lookup": false, "at-parser-buffer-size": 256, "at-parser-timeout": 8000 - }, - "target_overrides": { - "*": { - "target.features_add": ["COMMON_PAL"] - } } } \ No newline at end of file diff --git a/hal/modem_api.h b/features/netsocket/cellular/onboard_modem_api.h similarity index 60% rename from hal/modem_api.h rename to features/netsocket/cellular/onboard_modem_api.h index ac38e3feda..0e2a7df52c 100644 --- a/hal/modem_api.h +++ b/features/netsocket/cellular/onboard_modem_api.h @@ -14,42 +14,33 @@ * limitations under the License. */ +#ifndef ONBOARD_MODEM_API_H_ +#define ONBOARD_MODEM_API_H_ -#ifndef MODEM_API_H_ -#define MODEM_API_H_ - -/** modem_api is a standardizing API for Modem type devices under mbed-os. +/** onboard_modem_api is a standardizing API for Modem type devices under mbed-os. * It provides a simple hardware abstraction layer on top of the modem drivers * written for mbed-os. * - * It is required from the engineers porting any modem type device (e.g., Cellular or Wifi) + * It is required from the engineers porting any modem type device (e.g., Cellular) * to provide an implementation of this API in their respective target folder as well as - * usage of standard PinNames (in PinNames.h) is highly encouraged. For example, + * usage of standard PinNames (in PinNames.h) is required. For example, * - * MDMTXD = P0_15, // Transmit Data - * MDMRXD = P0_16, // Receive Data - * MDMCTS = P0_17, // Clear to Send - * MDMDCD = P0_18, // Data Carrier Detect - * MDMDSR = P0_19, // Data Set Ready - * MDMDTR = P0_20, // Data Terminal Ready (set high or use handshake) - * MDMRI = P0_21, // Ring Indicator - * MDMRTS = P0_22, // Request to Send (set high or use handshake) + * MDMTXD = P0_15, // Transmit Data + * MDMRXD = P0_16, // Receive Data + * MDMCTS = P0_17, // Clear to Send + * MDMDCD = P0_18, // Data Carrier Detect + * MDMDSR = P0_19, // Data Set Ready + * MDMDTR = P0_20, // Data Terminal Ready (set high or use handshake) + * MDMRI = P0_21, // Ring Indicator + * MDMRTS = P0_22, // Request to Send (set high or use handshake) * + * MDM_PIN_POLARITY must also be defined as 0 (active low) or 1 (active high). + * + * NOTE: This API should only be used when the modem exists on-board, i.e., the modem is + * NOT a plugged-in component. */ -#ifdef DEVICE_MODEM - -typedef enum { - POWER_READY=1, - POWERED_ON, - POWERED_OFF, - LOWEST_POWER_STATE -} modem_state; - -/** - * modem_s is defined in objects.h inside the TARGET folder - */ -typedef struct modem_s modem_t; +#if MODEM_ON_BOARD #ifdef __cplusplus extern "C" { @@ -59,30 +50,30 @@ extern "C" { * modem_init() will be equivalent to plugging in the device, i.e., * attaching power and serial port. */ -void modem_init(modem_t *obj); +void onboard_modem_init(void); /** Sets the modem in unplugged state * modem_deinit() will be equivalent to pulling the plug off of the device, i.e., * detaching power and serial port. * This puts the modem in lowest power state. */ -void modem_deinit(modem_t *obj); +void onboard_modem_deinit(void); /** Powers up the modem * modem_power_up() will be equivalent to pressing the soft power button. * The driver may repeat this if the modem is not responsive to AT commands. */ -void modem_power_up(modem_t *obj); +void onboard_modem_power_up(void); /** Powers down the modem * modem_power_down() will be equivalent to turning off the modem by button press. */ -void modem_power_down(modem_t *obj); +void onboard_modem_power_down(void); #ifdef __cplusplus } #endif -#endif /* DEVICE_MODEM*/ -#endif /* MODEM_API_H_ */ +#endif /* MODEM_ON_BOARD*/ +#endif /* ONBOARD_MODEM_API_H_ */ diff --git a/platform/APN_db.h b/features/netsocket/cellular/utils/APN_db.h similarity index 98% rename from platform/APN_db.h rename to features/netsocket/cellular/utils/APN_db.h index bd98d37b9c..040cb2bf42 100644 --- a/platform/APN_db.h +++ b/features/netsocket/cellular/utils/APN_db.h @@ -125,6 +125,7 @@ static const APN_t apnlut[] = { { /* Vodafone */ "234-15", _APN("internet","web","web") /* contract */ _APN("pp.vodafone.co.uk","wap","wap") /* pre-pay */ }, { /* Three */ "234-20", _APN("three.co.uk",,) }, + { /* Jersey */ "234-50", _APN("jtm2m",,) /* as used on u-blox C030 U201 boards */ }, // 310 United States of America - US { /* T-Mobile */ "310-026,260,490", diff --git a/platform/ATParser.cpp b/platform/ATCmdParser.cpp similarity index 93% rename from platform/ATParser.cpp rename to platform/ATCmdParser.cpp index afe47a0baf..6200f1fa4b 100644 --- a/platform/ATParser.cpp +++ b/platform/ATCmdParser.cpp @@ -18,7 +18,7 @@ * */ -#include "ATParser.h" +#include "ATCmdParser.h" #include "mbed_poll.h" #include "mbed_debug.h" @@ -37,7 +37,7 @@ #endif // getc/putc handling with timeouts -int ATParser::putc(char c) +int ATCmdParser::putc(char c) { pollfh fhs; fhs.fh = _fh; @@ -51,7 +51,7 @@ int ATParser::putc(char c) } } -int ATParser::getc() +int ATCmdParser::getc() { pollfh fhs; fhs.fh = _fh; @@ -66,7 +66,7 @@ int ATParser::getc() } } -void ATParser::flush() +void ATCmdParser::flush() { while (_fh->readable()) { unsigned char ch; @@ -76,7 +76,7 @@ void ATParser::flush() // read/write handling with timeouts -int ATParser::write(const char *data, int size) +int ATCmdParser::write(const char *data, int size) { int i = 0; for ( ; i < size; i++) { @@ -87,7 +87,7 @@ int ATParser::write(const char *data, int size) return i; } -int ATParser::read(char *data, int size) +int ATCmdParser::read(char *data, int size) { int i = 0; for ( ; i < size; i++) { @@ -102,7 +102,7 @@ int ATParser::read(char *data, int size) // printf/scanf handling -int ATParser::vprintf(const char *format, va_list args) +int ATCmdParser::vprintf(const char *format, va_list args) { if (vsprintf(_buffer, format, args) < 0) { @@ -118,7 +118,7 @@ int ATParser::vprintf(const char *format, va_list args) return i; } -int ATParser::vscanf(const char *format, va_list args) +int ATCmdParser::vscanf(const char *format, va_list args) { // Since format is const, we need to copy it into our buffer to // add the line's null terminator and clobber value-matches with asterisks. @@ -181,7 +181,7 @@ int ATParser::vscanf(const char *format, va_list args) // Command parsing with line handling -bool ATParser::vsend(const char *command, va_list args) +bool ATCmdParser::vsend(const char *command, va_list args) { // Create and send command if (vsprintf(_buffer, command, args) < 0) { @@ -205,7 +205,7 @@ bool ATParser::vsend(const char *command, va_list args) return true; } -bool ATParser::vrecv(const char *response, va_list args) +bool ATCmdParser::vrecv(const char *response, va_list args) { restart: _aborted = false; @@ -329,7 +329,7 @@ restart: } // Mapping to vararg functions -int ATParser::printf(const char *format, ...) +int ATCmdParser::printf(const char *format, ...) { va_list args; va_start(args, format); @@ -338,7 +338,7 @@ int ATParser::printf(const char *format, ...) return res; } -int ATParser::scanf(const char *format, ...) +int ATCmdParser::scanf(const char *format, ...) { va_list args; va_start(args, format); @@ -347,7 +347,7 @@ int ATParser::scanf(const char *format, ...) return res; } -bool ATParser::send(const char *command, ...) +bool ATCmdParser::send(const char *command, ...) { va_list args; va_start(args, command); @@ -356,7 +356,7 @@ bool ATParser::send(const char *command, ...) return res; } -bool ATParser::recv(const char *response, ...) +bool ATCmdParser::recv(const char *response, ...) { va_list args; va_start(args, response); @@ -366,7 +366,7 @@ bool ATParser::recv(const char *response, ...) } // oob registration -void ATParser::oob(const char *prefix, Callback cb) +void ATCmdParser::oob(const char *prefix, Callback cb) { struct oob *oob = new struct oob; oob->len = strlen(prefix); @@ -376,7 +376,7 @@ void ATParser::oob(const char *prefix, Callback cb) _oobs = oob; } -void ATParser::abort() +void ATCmdParser::abort() { _aborted = true; } diff --git a/platform/ATCmdParser.h b/platform/ATCmdParser.h new file mode 100644 index 0000000000..afdb7fb94b --- /dev/null +++ b/platform/ATCmdParser.h @@ -0,0 +1,297 @@ +/* Copyright (c) 2017 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. + * + * @section DESCRIPTION + * + * Parser for the AT command syntax + * + */ +#ifndef MBED_ATCMDPARSER_H +#define MBED_ATCMDPARSER_H + +#include "mbed.h" +#include +#include "Callback.h" + +/** + * Parser class for parsing AT commands + * + * Here are some examples: + * @code + * ATCmdParser at = ATCmdParser(serial, "\r\n"); + * int value; + * char buffer[100]; + * + * at.send("AT") && at.recv("OK"); + * at.send("AT+CWMODE=%d", 3) && at.recv("OK"); + * at.send("AT+CWMODE?") && at.recv("+CWMODE:%d\r\nOK", &value); + * at.recv("+IPD,%d:", &value); + * at.read(buffer, value); + * at.recv("OK"); + * @endcode + */ + +namespace mbed { + +class ATCmdParser +{ +private: + // File handle + // Not owned by ATCmdParser + FileHandle *_fh; + + int _buffer_size; + char *_buffer; + int _timeout; + + // Parsing information + const char *_output_delimiter; + int _output_delim_size; + char _in_prev; + bool _dbg_on; + bool _aborted; + + struct oob { + unsigned len; + const char *prefix; + mbed::Callback cb; + oob *next; + }; + oob *_oobs; + + // Prohibiting use of of copy constructor + ATCmdParser(const ATCmdParser &); + // Prohibiting copy assignment Operator + ATCmdParser &operator=(const ATCmdParser &); + +public: + + /** + * Constructor + * + * @param serial serial interface to use for AT commands + * @param buffer_size size of internal buffer for transaction + * @param timeout timeout of the connection + * @param debug turns on/off debug output for AT commands + */ + ATCmdParser(FileHandle *fh, const char *output_delimiter = "\r", + int buffer_size = 256, int timeout = 8000, bool debug = false) + : _fh(fh), _buffer_size(buffer_size), _in_prev(0), _oobs(NULL) + { + _buffer = new char[buffer_size]; + set_timeout(timeout); + set_delimiter(output_delimiter); + debug_on(debug); + } + + /** + * Destructor + */ + ~ATCmdParser() + { + while (_oobs) { + struct oob *oob = _oobs; + _oobs = oob->next; + delete oob; + } + delete[] _buffer; + } + + /** + * Allows timeout to be changed between commands + * + * @param timeout timeout of the connection + */ + void set_timeout(int timeout) + { + _timeout = timeout; + } + + /** + * For backwards compatibility. + * + * Please use set_timeout(int) API only from now on. + * Allows timeout to be changed between commands + * + * @param timeout timeout of the connection + */ + MBED_DEPRECATED_SINCE("mbed-os-5.5.0", "Replaced with set_timeout for consistency") + void setTimeout(int timeout) + { + set_timeout(timeout); + } + + /** + * Sets string of characters to use as line delimiters + * + * @param delimiter string of characters to use as line delimiters + */ + void set_delimiter(const char *output_delimiter) + { + _output_delimiter = output_delimiter; + _output_delim_size = strlen(output_delimiter); + } + + /** + * For backwards compatibility. + * + * Please use set_delimiter(const char *) API only from now on. + * Sets string of characters to use as line delimiters + * + * @param delimiter string of characters to use as line delimiters + */ + MBED_DEPRECATED_SINCE("mbed-os-5.5.0", "Replaced with set_delimiter for consistency") + void setDelimiter(const char *output_delimiter) + { + set_delimiter(output_delimiter); + } + + /** + * Allows traces from modem to be turned on or off + * + * @param on set as 1 to turn on traces and vice versa. + */ + void debug_on(uint8_t on) + { + _dbg_on = (on) ? 1 : 0; + } + + /** + * For backwards compatibility. + * + * Allows traces from modem to be turned on or off + * + * @param on set as 1 to turn on traces and vice versa. + */ + MBED_DEPRECATED_SINCE("mbed-os-5.5.0", "Replaced with debug_on for consistency") + void debugOn(uint8_t on) + { + debug_on(on); + } + + /** + * Sends an AT command + * + * Sends a formatted command using printf style formatting + * @see ::printf + * + * @param command printf-like format string of command to send which + * is appended with a newline + * @param ... all printf-like arguments to insert into command + * @return true only if command is successfully sent + */ + bool send(const char *command, ...) MBED_PRINTF_METHOD(1,2); + + bool vsend(const char *command, va_list args); + + /** + * Receive an AT response + * + * Receives a formatted response using scanf style formatting + * @see ::scanf + * + * Responses are parsed line at a time. + * Any received data that does not match the response is ignored until + * a timeout occurs. + * + * @param response scanf-like format string of response to expect + * @param ... all scanf-like arguments to extract from response + * @return true only if response is successfully matched + */ + bool recv(const char *response, ...) MBED_SCANF_METHOD(1,2); + + bool vrecv(const char *response, va_list args); + + /** + * Write a single byte to the underlying stream + * + * @param c The byte to write + * @return The byte that was written or -1 during a timeout + */ + int putc(char c); + + /** + * Get a single byte from the underlying stream + * + * @return The byte that was read or -1 during a timeout + */ + int getc(); + + /** + * Write an array of bytes to the underlying stream + * + * @param data the array of bytes to write + * @param size number of bytes to write + * @return number of bytes written or -1 on failure + */ + int write(const char *data, int size); + + /** + * Read an array of bytes from the underlying stream + * + * @param data the destination for the read bytes + * @param size number of bytes to read + * @return number of bytes read or -1 on failure + */ + int read(char *data, int size); + + /** + * Direct printf to underlying stream + * @see ::printf + * + * @param format format string to pass to printf + * @param ... arguments to printf + * @return number of bytes written or -1 on failure + */ + int printf(const char *format, ...) MBED_PRINTF_METHOD(1,2); + + int vprintf(const char *format, va_list args); + + /** + * Direct scanf on underlying stream + * @see ::scanf + * + * @param format format string to pass to scanf + * @param ... arguments to scanf + * @return number of bytes read or -1 on failure + */ + int scanf(const char *format, ...) MBED_SCANF_METHOD(1,2); + + int vscanf(const char *format, va_list args); + + /** + * Attach a callback for out-of-band data + * + * @param prefix string on when to initiate callback + * @param func callback to call when string is read + * @note out-of-band data is only processed during a scanf call + */ + void oob(const char *prefix, mbed::Callback func); + + /** + * Flushes the underlying stream + */ + void flush(); + + /** + * Abort current recv + * + * Can be called from oob handler to interrupt the current + * recv operation. + */ + void abort(); +}; +} //namespace mbed + +#endif //MBED_ATCMDPARSER_H diff --git a/platform/ATParser.h b/platform/ATParser.h deleted file mode 100644 index 55a8eb9d2a..0000000000 --- a/platform/ATParser.h +++ /dev/null @@ -1,290 +0,0 @@ -/* Copyright (c) 2017 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. - * - * @section DESCRIPTION - * - * Parser for the AT command syntax - * - */ -#ifndef MBED_ATPARSER_H -#define MBED_ATPARSER_H - -#include "mbed.h" -#include -#include "BufferedSerial.h" -#include "Callback.h" - - -/** -* Parser class for parsing AT commands -* -* Here are some examples: -* @code -* ATParser at = ATParser(serial, "\r\n"); -* int value; -* char buffer[100]; -* -* at.send("AT") && at.recv("OK"); -* at.send("AT+CWMODE=%d", 3) && at.recv("OK"); -* at.send("AT+CWMODE?") && at.recv("+CWMODE:%d\r\nOK", &value); -* at.recv("+IPD,%d:", &value); -* at.read(buffer, value); -* at.recv("OK"); -* @endcode -*/ -class ATParser -{ -private: - // File handle - // Not owned by ATParser - FileHandle *_fh; - - int _buffer_size; - char *_buffer; - int _timeout; - - // Parsing information - const char *_output_delimiter; - int _output_delim_size; - char _in_prev; - bool _dbg_on; - bool _aborted; - - struct oob { - unsigned len; - const char *prefix; - mbed::Callback cb; - oob *next; - }; - oob *_oobs; - - // Prohibiting use of of copy constructor - ATParser(const ATParser &); - // Prohibiting copy assignment Operator - ATParser &operator=(const ATParser &); - -public: - /** - * Constructor - * - * @param serial serial interface to use for AT commands - * @param buffer_size size of internal buffer for transaction - * @param timeout timeout of the connection - * @param debug turns on/off debug output for AT commands - */ - ATParser(FileHandle *fh, const char *output_delimiter="\r", int buffer_size = 256, int timeout = 8000, bool debug = false) : - _fh(fh), - _buffer_size(buffer_size), - _in_prev(0), - _oobs(NULL) { - _buffer = new char[buffer_size]; - set_timeout(timeout); - set_delimiter(output_delimiter); - debug_on(debug); - } - - /** - * Destructor - */ - ~ATParser() { - while (_oobs) { - struct oob *oob = _oobs; - _oobs = oob->next; - delete oob; - } - delete [] _buffer; - } - - /** - * Allows timeout to be changed between commands - * - * @param timeout timeout of the connection - */ - void set_timeout(int timeout) { - _timeout = timeout; - } - - /** - * For backwards compatibility. - * - * Please use set_timeout(int) API only from now on. - * Allows timeout to be changed between commands - * - * @param timeout timeout of the connection - */ - MBED_DEPRECATED_SINCE("mbed-os-5.5.0", "Replaced with set_timeout for consistency") - void setTimeout(int timeout) { - set_timeout(timeout); - } - - /** - * Sets string of characters to use as line delimiters - * - * @param delimiter string of characters to use as line delimiters - */ - void set_delimiter(const char *output_delimiter) - { - _output_delimiter = output_delimiter; - _output_delim_size = strlen(output_delimiter); - } - - /** - * For backwards compatibility. - * - * Please use set_delimiter(const char *) API only from now on. - * Sets string of characters to use as line delimiters - * - * @param delimiter string of characters to use as line delimiters - */ - MBED_DEPRECATED_SINCE("mbed-os-5.5.0", "Replaced with set_delimiter for consistency") - void setDelimiter(const char *output_delimiter) - { - set_delimiter(output_delimiter); - } - - /** - * Allows echo to be on or off - * - * @param echo 1 for echo and 0 turns it off - */ - void debug_on(uint8_t on) { - _dbg_on = (on) ? 1 : 0; - } - - /** - * For backwards compatibility. - * - * Allows echo to be on or off - * - * @param echo 1 for echo and 0 turns it off - */ - MBED_DEPRECATED_SINCE("mbed-os-5.5.0", "Replaced with debug_on for consistency") - void debugOn(uint8_t on) { - debug_on(on); - } - - /** - * Sends an AT command - * - * Sends a formatted command using printf style formatting - * @see ::printf - * - * @param command printf-like format string of command to send which - * is appended with a newline - * @param ... all printf-like arguments to insert into command - * @return true only if command is successfully sent - */ - bool send(const char *command, ...) MBED_PRINTF_METHOD(1,2); - - bool vsend(const char *command, va_list args); - - /** - * Receive an AT response - * - * Receives a formatted response using scanf style formatting - * @see ::scanf - * - * Responses are parsed line at a time. - * Any received data that does not match the response is ignored until - * a timeout occurs. - * - * @param response scanf-like format string of response to expect - * @param ... all scanf-like arguments to extract from response - * @return true only if response is successfully matched - */ - bool recv(const char *response, ...) MBED_SCANF_METHOD(1,2); - - bool vrecv(const char *response, va_list args); - - /** - * Write a single byte to the underlying stream - * - * @param c The byte to write - * @return The byte that was written or -1 during a timeout - */ - int putc(char c); - - /** - * Get a single byte from the underlying stream - * - * @return The byte that was read or -1 during a timeout - */ - int getc(); - - /** - * Write an array of bytes to the underlying stream - * - * @param data the array of bytes to write - * @param size number of bytes to write - * @return number of bytes written or -1 on failure - */ - int write(const char *data, int size); - - /** - * Read an array of bytes from the underlying stream - * - * @param data the destination for the read bytes - * @param size number of bytes to read - * @return number of bytes read or -1 on failure - */ - int read(char *data, int size); - - /** - * Direct printf to underlying stream - * @see ::printf - * - * @param format format string to pass to printf - * @param ... arguments to printf - * @return number of bytes written or -1 on failure - */ - int printf(const char *format, ...) MBED_PRINTF_METHOD(1,2); - - int vprintf(const char *format, va_list args); - - /** - * Direct scanf on underlying stream - * @see ::scanf - * - * @param format format string to pass to scanf - * @param ... arguments to scanf - * @return number of bytes read or -1 on failure - */ - int scanf(const char *format, ...) MBED_SCANF_METHOD(1,2); - - int vscanf(const char *format, va_list args); - - /** - * Attach a callback for out-of-band data - * - * @param prefix string on when to initiate callback - * @param func callback to call when string is read - * @note out-of-band data is only processed during a scanf call - */ - void oob(const char *prefix, mbed::Callback func); - - /** - * Flushes the underlying stream - */ - void flush(); - - /** - * Abort current recv - * - * Can be called from oob handler to interrupt the current - * recv operation. - */ - void abort(); -}; - -#endif //MBED_ATPARSER_H diff --git a/platform/BufferedSerial.h b/platform/BufferedSerial.h deleted file mode 100644 index 998a30d359..0000000000 --- a/platform/BufferedSerial.h +++ /dev/null @@ -1,111 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2017 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 MBED_BUFFEREDSERIAL_H -#define MBED_BUFFEREDSERIAL_H - -#include "platform/platform.h" - -#if DEVICE_SERIAL - -#include "FileHandle.h" -#include "SerialBase.h" -#include "InterruptIn.h" -#include "PlatformMutex.h" -#include "serial_api.h" -#include "CircularBuffer.h" - -namespace mbed { -class BufferedSerial : private SerialBase, public FileHandle { -public: - /** Create a BufferedSerial port, connected to the specified transmit and receive pins, with a particular baud rate. - * @param tx Transmit pin - * @param rx Receive pin - * @param baud The baud rate of the serial port (optional, defaults to MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE) - */ - BufferedSerial(PinName tx, PinName rx, int baud = MBED_CONF_PLATFORM_DEFAULT_SERIAL_BAUD_RATE); - virtual ~BufferedSerial(); - - /** Equivalent to POSIX poll(). Derived from FileHandle. - * Provides a mechanism to multiplex input/output over a set of file handles. - */ - virtual short poll(short events) const; - - virtual ssize_t write(const void* buffer, size_t length); - - virtual ssize_t read(void* buffer, size_t length); - - /** Acquire mutex */ - virtual void lock(void); - - /** Release mutex */ - virtual void unlock(void); - - virtual int close(); - - virtual int isatty(); - - virtual off_t seek(off_t offset, int whence); - - virtual int sync(); - - virtual int set_blocking(bool blocking) { _blocking = blocking; return 0; } - - virtual void sigio(Callback func); - - void set_data_carrier_detect(PinName DCD_pin, bool active_high=false); - - -private: - - /** Software serial buffers - * By default buffer size is 256 for TX and 256 for RX. Configurable through mbed_app.json - */ - CircularBuffer _rxbuf; - CircularBuffer _txbuf; - - PlatformMutex _mutex; - - Callback _sigio_cb; - - bool _blocking; - bool _tx_irq_enabled; - InterruptIn *_dcd; - - /** Device Hanged up - * Determines if the device hanged up on us. - * - * @return True, if hanged up - */ - bool hup() const; - - /** ISRs for serial - * Routines to handle interrupts on serial pins. - * Copies data into Circular Buffer. - * Reports the state change to File handle. - */ - void tx_irq(void); - void rx_irq(void); - - void wake(void); - - void DCD_IRQ(void); -}; -} //namespace mbed - - -#endif //DEVICE_SERIAL -#endif /* MBED_BUFFEREDSERIAL_H */ diff --git a/platform/mbed_lib.json b/platform/mbed_lib.json index b326b83b28..3185ed1886 100644 --- a/platform/mbed_lib.json +++ b/platform/mbed_lib.json @@ -19,14 +19,6 @@ "default-serial-baud-rate": { "help": "Default baud rate for a Serial or RawSerial instance (if not specified in the constructor)", "value": 9600 - }, - "buffered-serial-txbuf-size": { - "help": "Default TX buffer size for a BufferedSerial instance (unit Bytes))", - "value": 256 - }, - "buffered-serial-rxbuf-size": { - "help": "Default RX buffer size for a BufferedSerial instance (unit Bytes))", - "value": 256 } }, "target_overrides": { diff --git a/platform/mbed_retarget.cpp b/platform/mbed_retarget.cpp index 041765b562..b2782f42ae 100644 --- a/platform/mbed_retarget.cpp +++ b/platform/mbed_retarget.cpp @@ -124,6 +124,9 @@ static void init_serial() { /** * Sets errno when file opening fails. * Wipes out the filehandle too. + * + * @param error is a negative error code returned from an mbed function and + * will be negated to store a positive error code in errno */ static int handle_open_errors(int error, unsigned filehandle_idx) { errno = -error; diff --git a/targets/TARGET_NXP/TARGET_LPC176X/TARGET_UBLOX_C027/PinNames.h b/targets/TARGET_NXP/TARGET_LPC176X/TARGET_UBLOX_C027/PinNames.h index 4ccf24875c..304d8343e2 100644 --- a/targets/TARGET_NXP/TARGET_LPC176X/TARGET_UBLOX_C027/PinNames.h +++ b/targets/TARGET_NXP/TARGET_LPC176X/TARGET_UBLOX_C027/PinNames.h @@ -165,7 +165,7 @@ typedef enum { #define ACTIVE_HIGH_POLARITY 1 #define ACTIVE_LOW_POLARITY 0 -#define MDMDCD_POLARITY ACTIVE_LOW_POLARITY +#define MDM_PIN_POLARITY ACTIVE_LOW_POLARITY typedef enum { PullUp = 0, diff --git a/targets/TARGET_NXP/TARGET_LPC176X/TARGET_UBLOX_C027/mbed_modem_api.c b/targets/TARGET_NXP/TARGET_LPC176X/TARGET_UBLOX_C027/onboard_modem_api.c similarity index 80% rename from targets/TARGET_NXP/TARGET_LPC176X/TARGET_UBLOX_C027/mbed_modem_api.c rename to targets/TARGET_NXP/TARGET_LPC176X/TARGET_UBLOX_C027/onboard_modem_api.c index 3800300835..7849f78737 100644 --- a/targets/TARGET_NXP/TARGET_LPC176X/TARGET_UBLOX_C027/mbed_modem_api.c +++ b/targets/TARGET_NXP/TARGET_LPC176X/TARGET_UBLOX_C027/onboard_modem_api.c @@ -14,13 +14,16 @@ * limitations under the License. */ -#include "modem_api.h" +#if MBED_CONF_NSAPI_PRESENT + +#include "cellular/onboard_modem_api.h" #include "ublox_low_level_api.h" #include "gpio_api.h" #include "platform/mbed_wait_api.h" #include "PinNames.h" -#if DEVICE_MODEM +#if MODEM_ON_BOARD + static void press_power_button(int time_ms) { gpio_t gpio; @@ -30,32 +33,30 @@ static void press_power_button(int time_ms) gpio_write(&gpio, 1); } -void modem_init(modem_t *obj) +void onboard_modem_init() { //currently USB is not supported, so pass 0 to disable USB //This call does everything except actually pressing the power button ublox_mdm_powerOn(0); - obj->state = POWER_READY; } -void modem_deinit(modem_t *obj) +void onboard_modem_deinit() { ublox_mdm_powerOff(); - obj->state = LOWEST_POWER_STATE; } -void modem_power_up(modem_t *obj) + +void onboard_modem_power_up() { /* keep the power line low for 150 milisecond */ press_power_button(150); /* give modem a little time to respond */ wait_ms(100); - obj->state = POWERED_ON; } -void modem_power_down(modem_t *obj) +void onboard_modem_power_down() { /* keep the power line low for 1 second */ press_power_button(1000); - obj->state = POWERED_OFF; } -#endif //DEVICE_MODEM +#endif //MODEM_ON_BOARD +#endif //MBED_CONF_NSAPI_PRESENT diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_MTS_DRAGONFLY_F411RE/PinNames.h b/targets/TARGET_STM/TARGET_STM32F4/TARGET_MTS_DRAGONFLY_F411RE/PinNames.h index 2ec6718f53..ca73457e6e 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_MTS_DRAGONFLY_F411RE/PinNames.h +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_MTS_DRAGONFLY_F411RE/PinNames.h @@ -195,7 +195,7 @@ typedef enum { #define ACTIVE_HIGH_POLARITY 1 #define ACTIVE_LOW_POLARITY 0 -#define MDMDCD_POLARITY ACTIVE_HIGH_POLARITY +#define MDM_PIN_POLARITY ACTIVE_HIGH_POLARITY #ifdef __cplusplus diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_MTS_DRAGONFLY_F411RE/objects.h b/targets/TARGET_STM/TARGET_STM32F4/TARGET_MTS_DRAGONFLY_F411RE/objects.h index cf1fe61392..d423c5ebef 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_MTS_DRAGONFLY_F411RE/objects.h +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_MTS_DRAGONFLY_F411RE/objects.h @@ -60,10 +60,6 @@ struct analogin_s { uint8_t channel; }; -struct modem_s { - uint32_t state; -}; - #include "common_objects.h" #ifdef __cplusplus diff --git a/targets/TARGET_STM/TARGET_STM32F4/TARGET_MTS_DRAGONFLY_F411RE/mbed_modem_api.c b/targets/TARGET_STM/TARGET_STM32F4/TARGET_MTS_DRAGONFLY_F411RE/onboard_modem_api.c similarity index 83% rename from targets/TARGET_STM/TARGET_STM32F4/TARGET_MTS_DRAGONFLY_F411RE/mbed_modem_api.c rename to targets/TARGET_STM/TARGET_STM32F4/TARGET_MTS_DRAGONFLY_F411RE/onboard_modem_api.c index fb06728fc9..ea532df442 100644 --- a/targets/TARGET_STM/TARGET_STM32F4/TARGET_MTS_DRAGONFLY_F411RE/mbed_modem_api.c +++ b/targets/TARGET_STM/TARGET_STM32F4/TARGET_MTS_DRAGONFLY_F411RE/onboard_modem_api.c @@ -13,12 +13,16 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include "modem_api.h" + +#if MBED_CONF_NSAPI_PRESENT + +#include "cellular/onboard_modem_api.h" #include "gpio_api.h" #include "platform/mbed_wait_api.h" #include "PinNames.h" -#if DEVICE_MODEM +#if MODEM_ON_BOARD + static void press_power_button(int time_ms) { gpio_t gpio; @@ -29,27 +33,24 @@ static void press_power_button(int time_ms) gpio_write(&gpio, 1); } -void modem_init(modem_t *obj) +void onboard_modem_init() { //does nothing at the moment, TODO: MultiTech to add hardware initialization stuff if needed - obj->state = POWER_READY; } -void modem_deinit(modem_t *obj) +void onboard_modem_deinit() { //does nothing at the moment, TODO: MultiTech to add hardware de-initialization stuff if needed - obj->state = LOWEST_POWER_STATE; } -void modem_power_up(modem_t *obj) +void onboard_modem_power_up() { /* keep the power line low for 200 milisecond */ press_power_button(200); /* give modem a little time to respond */ wait_ms(100); - obj->state = POWERED_ON; } -void modem_power_down(modem_t *obj) +void onboard_modem_power_down() { gpio_t gpio; @@ -59,6 +60,6 @@ void modem_power_down(modem_t *obj) * place, Due to the network disconnect, shut-off can take up to 30 seconds. However, we wait for 10 * seconds only */ wait_ms(10*1000); - obj->state = POWERED_OFF; } -#endif //DEVICE_MODEM +#endif //MODEM_ON_BOARD +#endif //MBED_CONF_NSAPI_PRESENT diff --git a/targets/targets.json b/targets/targets.json index 50a301d932..2f6d4e7c2f 100644 --- a/targets/targets.json +++ b/targets/targets.json @@ -248,10 +248,22 @@ "supported_form_factors": ["ARDUINO"], "core": "Cortex-M3", "supported_toolchains": ["ARM", "uARM", "GCC_ARM", "GCC_CR", "IAR"], - "extra_labels": ["NXP", "LPC176X", "FLASH_CMSIS_ALGO", "UBLOX_MODEM_GENERIC", "GENERIC_MODEM"], + "extra_labels": ["NXP", "LPC176X", "FLASH_CMSIS_ALGO", "UBLOX_MODEM_GENERIC"], + "config": { + "modem_is_on_board": { + "help": "Value: Tells the build system that the modem is on-board as oppose to a plug-in shield/module.", + "value": 1, + "macro_name": "MODEM_ON_BOARD" + }, + "modem_data_connection_type": { + "help": "Value: Defines how the modem is wired up to the MCU, e.g., data connection can be a UART or USB and so forth.", + "value": 1, + "macro_name": "MODEM_ON_BOARD_UART" + } + }, "macros": ["TARGET_LPC1768"], "inherits": ["LPCTarget"], - "device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "DEBUG_AWARENESS", "ERROR_RED", "ETHERNET", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES", "FLASH", "MODEM"], + "device_has": ["ANALOGIN", "ANALOGOUT", "CAN", "DEBUG_AWARENESS", "ERROR_RED", "ETHERNET", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SERIAL_FC", "SLEEP", "SPI", "SPISLAVE", "STDIO_MESSAGES", "FLASH"], "release_versions": ["2", "5"], "features": ["LWIP"], "device_name": "LPC1768" @@ -1337,13 +1349,25 @@ "inherits": ["Target"], "core": "Cortex-M4F", "supported_toolchains": ["ARM", "uARM", "GCC_ARM", "IAR"], - "extra_labels": ["STM", "STM32F4", "STM32F411RE", "DRAGONFLY_MODEM", "GENERIC_MODEM"], + "extra_labels": ["STM", "STM32F4", "STM32F411RE"], + "config": { + "modem_is_on_board": { + "help": "Value: Tells the build system that the modem is on-board as oppose to a plug-in shield/module.", + "value": 1, + "macro_name": "MODEM_ON_BOARD" + }, + "modem_data_connection_type": { + "help": "Value: Defines how an on-board modem is wired up to the MCU, e.g., data connection can be a UART or USB and so forth.", + "value": 1, + "macro_name": "MODEM_ON_BOARD_UART" + } + }, "macros": ["HSE_VALUE=26000000", "VECT_TAB_OFFSET=0x08010000","TRANSACTION_QUEUE_SIZE_SPI=2", "RTC_LSI=1"], "post_binary_hook": { "function": "MTSCode.combine_bins_mts_dragonfly", "toolchains": ["GCC_ARM", "ARM_STD", "ARM_MICRO"] }, - "device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES", "MODEM"], + "device_has": ["ANALOGIN", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "SPI_ASYNCH", "STDIO_MESSAGES"], "release_versions": ["2", "5"], "device_name": "STM32F411RE" },