diff --git a/features/cellular/framework/targets/TELIT/ME910/TELIT_ME910.cpp b/features/cellular/framework/targets/TELIT/ME910/TELIT_ME910.cpp new file mode 100644 index 0000000000..6c7c7c1483 --- /dev/null +++ b/features/cellular/framework/targets/TELIT/ME910/TELIT_ME910.cpp @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2017, Arm Limited and affiliates. + * SPDX-License-Identifier: Apache-2.0 + * + * 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 "TELIT_ME910.h" +#include "TELIT_ME910_CellularContext.h" +#include "AT_CellularNetwork.h" +#include "PinNames.h" +#include "rtos/ThisThread.h" + +using namespace mbed; +using namespace rtos; +using namespace events; + +#if !defined(MBED_CONF_TELIT_ME910_PWR) +#define MBED_CONF_TELIT_ME910_PWR NC +#endif + +#if !defined(MBED_CONF_TELIT_ME910_TX) +#define MBED_CONF_TELIT_ME910_TX NC +#endif + +#if !defined(MBED_CONF_TELIT_ME910_RX) +#define MBED_CONF_TELIT_ME910_RX NC +#endif + +#if !defined(MBED_CONF_TELIT_ME910_POLARITY) +#define MBED_CONF_TELIT_ME910_POLARITY 1 // active high +#endif + +static const intptr_t cellular_properties[AT_CellularBase::PROPERTY_MAX] = { + AT_CellularNetwork::RegistrationModeLAC, // C_EREG + AT_CellularNetwork::RegistrationModeLAC, // C_GREG + AT_CellularNetwork::RegistrationModeLAC, // C_REG + 0, // AT_CGSN_WITH_TYPE + 0, // AT_CGDATA + 1, // AT_CGAUTH + 1, // AT_CNMI + 1, // AT_CSMP + 1, // AT_CMGF + 1, // AT_CSDH + 1, // PROPERTY_IPV4_STACK + 1, // PROPERTY_IPV6_STACK + 1, // PROPERTY_IPV4V6_STACK + 0, // PROPERTY_NON_IP_PDP_TYPE + 1, // PROPERTY_AT_CGEREP +}; + +//the delay between sending AT commands +static const uint16_t DEFAULT_DELAY_BETWEEN_AT_COMMANDS = 20; + +TELIT_ME910::TELIT_ME910(FileHandle *fh, PinName pwr, bool active_high) + : AT_CellularDevice(fh), + _active_high(active_high), + _pwr_key(pwr, !_active_high) +{ + AT_CellularBase::set_cellular_properties(cellular_properties); +} + +AT_CellularContext *TELIT_ME910::create_context_impl(ATHandler &at, const char *apn, bool cp_req, bool nonip_req) +{ + return new TELIT_ME910_CellularContext(at, this, apn, cp_req, nonip_req); +} + + +uint16_t TELIT_ME910::get_send_delay() const +{ + return DEFAULT_DELAY_BETWEEN_AT_COMMANDS; +} + +nsapi_error_t TELIT_ME910::init() +{ + nsapi_error_t err = AT_CellularDevice::init(); + if (err != NSAPI_ERROR_OK) { + return err; + } + _at->lock(); +#if defined (MBED_CONF_TELIT_ME910_RTS) && defined (MBED_CONF_TELIT_ME910_CTS) + _at->cmd_start("AT&K3;&C1;&D0"); +#else + _at->cmd_start("AT&K0;&C1;&D0"); +#endif + _at->cmd_stop_read_resp(); + + // AT#QSS=1 + // Enable the Query SIM Status unsolicited indication in the ME. The format of the + // unsolicited indication is the following: + // #QSS: + // The ME informs at + // every SIM status change through the basic unsolicited indication where range is 0...1 + // values: + // - 0: SIM not inserted + // - 1: SIM inserted + _at->cmd_start("AT#QSS=1"); + _at->cmd_stop_read_resp(); + + // AT#PSNT=1 + // Set command enables unsolicited result code for packet service network type (PSNT) + // having the following format: + // #PSNT: + // values: + // - 0: GPRS network + // - 4: LTE network + // - 5: unknown or not registered + _at->cmd_start("AT#PSNT=1"); + _at->cmd_stop_read_resp(); + + // AT+CMER=2 + // Set command enables sending of unsolicited result codes from TA to TE in the case of + // indicator state changes. + // Current setting: buffer +CIEV Unsolicited Result Codes in the TA when TA-TE link is + // reserved (e.g. on-line data mode) and flush them to the TE after + // reservation; otherwise forward them directly to the TE + _at->cmd_start("AT+CMER=2"); + _at->cmd_stop_read_resp(); + + // AT+CMEE=2 + // Set command disables the use of result code +CME ERROR: as an indication of an + // error relating to the +Cxxx command issued. When enabled, device related errors cause the +CME + // ERROR: final result code instead of the default ERROR final result code. ERROR is returned + // normally when the error message is related to syntax, invalid parameters or DTE functionality. + // Current setting: enable and use verbose values + _at->cmd_start("AT+CMEE=2"); + _at->cmd_stop_read_resp(); + + // AT&W&P + // - AT&W: Execution command stores on profile the complete configuration of the device. If + // parameter is omitted, the command has the same behavior of AT&W0. + // - AT&P: Execution command defines which full profile will be loaded at startup. If parameter + // is omitted, the command has the same behavior as AT&P0 + _at->cmd_start("AT&W&P"); + _at->cmd_stop_read_resp(); + + return _at->unlock_return_error(); +} + +#if MBED_CONF_TELIT_ME910_PROVIDE_DEFAULT +#include "UARTSerial.h" +CellularDevice *CellularDevice::get_default_instance() +{ + static UARTSerial serial(MBED_CONF_TELIT_ME910_TX, MBED_CONF_TELIT_ME910_RX, MBED_CONF_TELIT_ME910_BAUDRATE); +#if defined (MBED_CONF_TELIT_ME910_RTS) && defined (MBED_CONF_TELIT_ME910_CTS) + serial.set_flow_control(SerialBase::RTSCTS, MBED_CONF_TELIT_ME910_RTS, MBED_CONF_TELIT_ME910_CTS); +#endif + static TELIT_ME910 device(&serial, + MBED_CONF_TELIT_ME910_PWR, + MBED_CONF_TELIT_ME910_POLARITY); + return &device; +} +#endif + +nsapi_error_t TELIT_ME910::hard_power_on() +{ + soft_power_on(); + + return NSAPI_ERROR_OK; +} + +nsapi_error_t TELIT_ME910::soft_power_on() +{ + _pwr_key = _active_high; + ThisThread::sleep_for(500); + _pwr_key = !_active_high; + ThisThread::sleep_for(5000); + _pwr_key = _active_high; + ThisThread::sleep_for(5000); + + return NSAPI_ERROR_OK; +} + +nsapi_error_t TELIT_ME910::hard_power_off() +{ + _pwr_key = !_active_high; + ThisThread::sleep_for(10000); + + return NSAPI_ERROR_OK; +} + +nsapi_error_t TELIT_ME910::soft_power_off() +{ + return AT_CellularDevice::soft_power_off(); +} diff --git a/features/cellular/framework/targets/TELIT/ME910/TELIT_ME910.h b/features/cellular/framework/targets/TELIT/ME910/TELIT_ME910.h new file mode 100644 index 0000000000..6b0455d3fb --- /dev/null +++ b/features/cellular/framework/targets/TELIT/ME910/TELIT_ME910.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2017, Arm Limited and affiliates. + * SPDX-License-Identifier: Apache-2.0 + * + * 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_TARGETS_TELIT_ME910_TELIT_ME910_H_ +#define CELLULAR_TARGETS_TELIT_ME910_TELIT_ME910_H_ + +#ifdef TARGET_FF_ARDUINO +#ifndef MBED_CONF_TELIT_ME910_TX +#define MBED_CONF_TELIT_ME910_TX D1 +#endif +#ifndef MBED_CONF_TELIT_ME910_RX +#define MBED_CONF_TELIT_ME910_RX D0 +#endif +#endif /* TARGET_FF_ARDUINO */ + +#include "DigitalOut.h" +#include "AT_CellularDevice.h" + +namespace mbed { + +class TELIT_ME910 : public AT_CellularDevice { +public: + /** + * Constructs the Telit ME910 series driver. It is mandatory to provide + * a FileHandle object, the power pin and the polarity of the pin. + */ + TELIT_ME910(FileHandle *fh, PinName pwr, bool active_high); + +protected: // AT_CellularDevice + virtual uint16_t get_send_delay() const; + virtual AT_CellularContext *create_context_impl(ATHandler &at, const char *apn, bool cp_req = false, bool nonip_req = false); + virtual nsapi_error_t init(); + virtual nsapi_error_t hard_power_on(); + virtual nsapi_error_t hard_power_off(); + virtual nsapi_error_t soft_power_on(); + virtual nsapi_error_t soft_power_off(); +private: + bool _active_high; + DigitalOut _pwr_key; +}; +} // namespace mbed +#endif /* CELLULAR_TARGETS_TELIT_ME910_TELIT_ME910_H_ */ diff --git a/features/cellular/framework/targets/TELIT/ME910/TELIT_ME910_CellularContext.cpp b/features/cellular/framework/targets/TELIT/ME910/TELIT_ME910_CellularContext.cpp new file mode 100644 index 0000000000..ff286f2f16 --- /dev/null +++ b/features/cellular/framework/targets/TELIT/ME910/TELIT_ME910_CellularContext.cpp @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2018, Arm Limited and affiliates. + * SPDX-License-Identifier: Apache-2.0 + * + * 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 "TELIT_ME910_CellularContext.h" +#include "CellularLog.h" + +#include "Semaphore.h" + +namespace mbed { + +TELIT_ME910_CellularContext::TELIT_ME910_CellularContext(ATHandler &at, CellularDevice *device, const char *apn, bool cp_req, bool nonip_req) : + AT_CellularContext(at, device, apn, cp_req, nonip_req) +{ +} + +TELIT_ME910_CellularContext::~TELIT_ME910_CellularContext() +{ +} + +bool TELIT_ME910_CellularContext::get_context() +{ + bool modem_supports_ipv6 = get_property(PROPERTY_IPV6_PDP_TYPE); + bool modem_supports_ipv4 = get_property(PROPERTY_IPV4_PDP_TYPE); + _at.cmd_start("AT+CGDCONT?"); + _at.cmd_stop(); + _at.resp_start("+CGDCONT:"); + _cid = -1; + int cid_max = 0; // needed when creating new context + char apn[MAX_ACCESSPOINT_NAME_LENGTH]; + int apn_len = 0; + + while (_at.info_resp()) { + int cid = _at.read_int(); + if (cid > cid_max) { + cid_max = cid; + } + char pdp_type_from_context[10]; + int pdp_type_len = _at.read_string(pdp_type_from_context, sizeof(pdp_type_from_context) - 1); + if (pdp_type_len > 0) { + apn_len = _at.read_string(apn, sizeof(apn) - 1); + if (apn_len >= 0) { + if (_apn && apn_len > 0 && (strcmp(apn, _apn) != 0)) { + continue; + } + + // APN matched -> Check PDP type + pdp_type_t pdp_type = string_to_pdp_type(pdp_type_from_context); + + // Accept exact matching PDP context type or dual PDP context for IPv4/IPv6 only modems + if (get_property(pdp_type_t_to_cellular_property(pdp_type)) || + ((pdp_type == IPV4V6_PDP_TYPE && (modem_supports_ipv4 || modem_supports_ipv6)) && !_nonip_req)) { + _pdp_type = pdp_type; + _cid = cid; + break; + } + } + } + } + + _at.resp_stop(); + if (_cid == -1) { // no suitable context was found so create a new one + if (!set_new_context(1)) { + return false; + } + } + + // save the apn + if (apn_len > 0 && !_apn) { + memcpy(_found_apn, apn, apn_len + 1); + } + + tr_info("Found PDP context %d", _cid); + return true; +} + +} /* namespace mbed */ diff --git a/features/cellular/framework/targets/TELIT/ME910/TELIT_ME910_CellularContext.h b/features/cellular/framework/targets/TELIT/ME910/TELIT_ME910_CellularContext.h new file mode 100644 index 0000000000..2f373ca792 --- /dev/null +++ b/features/cellular/framework/targets/TELIT/ME910/TELIT_ME910_CellularContext.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2018, Arm Limited and affiliates. + * SPDX-License-Identifier: Apache-2.0 + * + * 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 TELIT_ME910_CELLULARCONTEXT_H_ +#define TELIT_ME910_CELLULARCONTEXT_H_ + +#include "AT_CellularContext.h" + +namespace mbed { + +class TELIT_ME910_CellularContext: public AT_CellularContext { +public: + TELIT_ME910_CellularContext(ATHandler &at, CellularDevice *device, const char *apn, bool cp_req = false, bool nonip_req = false); + virtual ~TELIT_ME910_CellularContext(); +protected: + virtual bool get_context(); +}; + +} /* namespace mbed */ + +#endif // TELIT_ME910_CELLULARCONTEXT_H_ diff --git a/features/cellular/framework/targets/TELIT/ME910/mbed_lib.json b/features/cellular/framework/targets/TELIT/ME910/mbed_lib.json new file mode 100644 index 0000000000..e70e703354 --- /dev/null +++ b/features/cellular/framework/targets/TELIT/ME910/mbed_lib.json @@ -0,0 +1,38 @@ +{ + "name": "TELIT_ME910", + "config": { + "tx": { + "help": "TX pin for serial connection. D1 assumed if Arduino Form Factor, needs to be set/overwritten otherwise.", + "value": null + }, + "rx": { + "help": "RX pin for serial connection. D0 assumed if Arduino Form Factor, needs to be set/overwritten otherwise.", + "value": null + }, + "rts": { + "help": "RTS pin for serial connection", + "value": null + }, + "cts": { + "help": "CTS pin for serial connection", + "value": null + }, + "pwr": { + "help": "Power control pin", + "value": null + }, + "polarity": { + "help": "Pin polarity, 1 = Active high, 0 = Active low", + "value": null + }, + "baudrate" : { + "help": "Serial connection baud rate", + "value": 115200 + }, + "provide-default": { + "help": "Provide as default CellularDevice [true/false]", + "value": false + } + } +} +