mirror of https://github.com/ARMmbed/mbed-os.git
Modify ME910 driver to follow power on/off best practices and add custom get_context() function
parent
cbea74820e
commit
a214a3cb59
|
@ -16,13 +16,31 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "TELIT_ME910.h"
|
#include "TELIT_ME910.h"
|
||||||
|
#include "TELIT_ME910_CellularContext.h"
|
||||||
#include "AT_CellularNetwork.h"
|
#include "AT_CellularNetwork.h"
|
||||||
#include "gpio_api.h"
|
#include "PinNames.h"
|
||||||
#include "platform/mbed_wait_api.h"
|
#include "rtos/ThisThread.h"
|
||||||
|
|
||||||
using namespace mbed;
|
using namespace mbed;
|
||||||
|
using namespace rtos;
|
||||||
using namespace events;
|
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] = {
|
static const intptr_t cellular_properties[AT_CellularBase::PROPERTY_MAX] = {
|
||||||
AT_CellularNetwork::RegistrationModeLAC, // C_EREG
|
AT_CellularNetwork::RegistrationModeLAC, // C_EREG
|
||||||
AT_CellularNetwork::RegistrationModeLAC, // C_GREG
|
AT_CellularNetwork::RegistrationModeLAC, // C_GREG
|
||||||
|
@ -41,11 +59,20 @@ static const intptr_t cellular_properties[AT_CellularBase::PROPERTY_MAX] = {
|
||||||
1, // PROPERTY_AT_CGEREP
|
1, // PROPERTY_AT_CGEREP
|
||||||
};
|
};
|
||||||
|
|
||||||
TELIT_ME910::TELIT_ME910(FileHandle *fh) : AT_CellularDevice(fh)
|
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_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
|
uint16_t TELIT_ME910::get_send_delay() const
|
||||||
{
|
{
|
||||||
return DEFAULT_DELAY_BETWEEN_AT_COMMANDS;
|
return DEFAULT_DELAY_BETWEEN_AT_COMMANDS;
|
||||||
|
@ -65,6 +92,99 @@ nsapi_error_t TELIT_ME910::init()
|
||||||
#endif
|
#endif
|
||||||
_at->cmd_stop_read_resp();
|
_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: <status>
|
||||||
|
// The ME informs at
|
||||||
|
// every SIM status change through the basic unsolicited indication where <status> range is 0...1
|
||||||
|
// <status> 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:<nt>
|
||||||
|
// <nt> values:
|
||||||
|
// - 0: GPRS network
|
||||||
|
// - 4: LTE network
|
||||||
|
// - 5: unknown or not registered
|
||||||
|
_at->cmd_start("AT#PSNT=1");
|
||||||
|
_at->cmd_stop_read_resp();
|
||||||
|
|
||||||
|
// AT+CGEREP=2
|
||||||
|
// Set command enables sending of unsolicited result codes in case of certain events
|
||||||
|
// occurring in the module or in the network.
|
||||||
|
// Current setting: buffer unsolicited result codes in the TA when TA-TE link is reserved (e.g.
|
||||||
|
// in on-line data mode) and flush them to the TE when TA-TE link becomes
|
||||||
|
// available; otherwise forward them directly to the TE.
|
||||||
|
_at->cmd_start("AT+CGEREP=2");
|
||||||
|
_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+CREG=1
|
||||||
|
// Set command enables the network registration unsolicited result code and selects one of
|
||||||
|
// the two available formats:
|
||||||
|
// short format: +CREG: <stat>
|
||||||
|
// long format: +CREG: <stat>[,<lac>,<ci>[,<AcT>]]
|
||||||
|
// Current setting: enable the network registration unsolicited result code, and selects the
|
||||||
|
// short format
|
||||||
|
_at->cmd_start("AT+CREG=1");
|
||||||
|
_at->cmd_stop_read_resp();
|
||||||
|
|
||||||
|
// AT+CGREG=1
|
||||||
|
// Set command enables/disables the +CGREG: unsolicited result code, and selects one of the
|
||||||
|
// available formats:
|
||||||
|
// short format:
|
||||||
|
// +CGREG:<stat>
|
||||||
|
// long format:
|
||||||
|
// +CGREG:<stat>[,<lac>,<ci>[,<AcT>,<rac>]]
|
||||||
|
// extra long format:
|
||||||
|
// +CGREG:<stat>[,[<lac>],[<ci>],[<AcT>],[<rac>][,,[,[<ActiveTime>],[<PeriodicRAU>],[<GPRSREADYtimer>]]]]
|
||||||
|
// Current setting: enable the network registration unsolicited result code, and selects the
|
||||||
|
// short format
|
||||||
|
_at->cmd_start("AT+CGREG=1");
|
||||||
|
_at->cmd_stop_read_resp();
|
||||||
|
|
||||||
|
// AT+CEREG=1
|
||||||
|
// Set command enables the EPS network registration unsolicited result code (URC) in LTE,
|
||||||
|
// and selects one of the available formats:
|
||||||
|
// short format: +CEREG: <stat>
|
||||||
|
// long format: +CEREG: <stat>[,[<tac>],[<ci>],[<AcT>]]
|
||||||
|
// <tac>, <ci>, and <AcT> are reported by the command only if available.
|
||||||
|
// Current setting: enable the network registration unsolicited result code, and select the short
|
||||||
|
// format
|
||||||
|
_at->cmd_start("AT+CEREG=1");
|
||||||
|
_at->cmd_stop_read_resp();
|
||||||
|
|
||||||
|
// AT+CMEE=2
|
||||||
|
// Set command disables the use of result code +CME ERROR: <err> as an indication of an
|
||||||
|
// error relating to the +Cxxx command issued. When enabled, device related errors cause the +CME
|
||||||
|
// ERROR: <err> 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 <err> values
|
||||||
|
_at->cmd_start("AT+CMEE=2");
|
||||||
|
_at->cmd_stop_read_resp();
|
||||||
|
|
||||||
|
// AT&W&P
|
||||||
|
// - AT&W: Execution command stores on profile <n> 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();
|
return _at->unlock_return_error();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,7 +196,9 @@ CellularDevice *CellularDevice::get_default_instance()
|
||||||
#if defined (MBED_CONF_TELIT_ME910_RTS) && defined (MBED_CONF_TELIT_ME910_CTS)
|
#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);
|
serial.set_flow_control(SerialBase::RTSCTS, MBED_CONF_TELIT_ME910_RTS, MBED_CONF_TELIT_ME910_CTS);
|
||||||
#endif
|
#endif
|
||||||
static TELIT_ME910 device(&serial);
|
static TELIT_ME910 device(&serial,
|
||||||
|
MBED_CONF_TELIT_ME910_PWR,
|
||||||
|
MBED_CONF_TELIT_ME910_POLARITY);
|
||||||
return &device;
|
return &device;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -90,28 +212,20 @@ nsapi_error_t TELIT_ME910::hard_power_on()
|
||||||
|
|
||||||
nsapi_error_t TELIT_ME910::soft_power_on()
|
nsapi_error_t TELIT_ME910::soft_power_on()
|
||||||
{
|
{
|
||||||
gpio_t gpio;
|
_pwr_key = _active_high;
|
||||||
|
ThisThread::sleep_for(500);
|
||||||
gpio_init_out_ex(&gpio, MDMPWRON, 1);
|
_pwr_key = !_active_high;
|
||||||
wait_ms(500);
|
ThisThread::sleep_for(5000);
|
||||||
gpio_write(&gpio, 0);
|
_pwr_key = _active_high;
|
||||||
wait_ms(5000);
|
ThisThread::sleep_for(5000);
|
||||||
gpio_write(&gpio, 1);
|
|
||||||
wait_ms(5000);
|
|
||||||
|
|
||||||
return NSAPI_ERROR_OK;
|
return NSAPI_ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsapi_error_t TELIT_ME910::hard_power_off()
|
nsapi_error_t TELIT_ME910::hard_power_off()
|
||||||
{
|
{
|
||||||
gpio_t gpio;
|
_pwr_key = !_active_high;
|
||||||
|
ThisThread::sleep_for(10000);
|
||||||
gpio_init_out_ex(&gpio, MDMPWRON, 0);
|
|
||||||
/* keep the power line low for more than 10 seconds.
|
|
||||||
* If 3G_ON_OFF pin is kept low for more than a second, a controlled disconnect and shutdown takes
|
|
||||||
* 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);
|
|
||||||
|
|
||||||
return NSAPI_ERROR_OK;
|
return NSAPI_ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#endif
|
#endif
|
||||||
#endif /* TARGET_FF_ARDUINO */
|
#endif /* TARGET_FF_ARDUINO */
|
||||||
|
|
||||||
|
#include "DigitalOut.h"
|
||||||
#include "AT_CellularDevice.h"
|
#include "AT_CellularDevice.h"
|
||||||
|
|
||||||
//the delay between sending AT commands
|
//the delay between sending AT commands
|
||||||
|
@ -36,15 +37,23 @@ namespace mbed {
|
||||||
|
|
||||||
class TELIT_ME910 : public AT_CellularDevice {
|
class TELIT_ME910 : public AT_CellularDevice {
|
||||||
public:
|
public:
|
||||||
TELIT_ME910(FileHandle *fh);
|
/**
|
||||||
|
* 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
|
protected: // AT_CellularDevice
|
||||||
virtual uint16_t get_send_delay() const;
|
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 init();
|
||||||
virtual nsapi_error_t hard_power_on();
|
virtual nsapi_error_t hard_power_on();
|
||||||
virtual nsapi_error_t hard_power_off();
|
virtual nsapi_error_t hard_power_off();
|
||||||
virtual nsapi_error_t soft_power_on();
|
virtual nsapi_error_t soft_power_on();
|
||||||
virtual nsapi_error_t soft_power_off();
|
virtual nsapi_error_t soft_power_off();
|
||||||
|
private:
|
||||||
|
bool _active_high;
|
||||||
|
DigitalOut _pwr_key;
|
||||||
};
|
};
|
||||||
} // namespace mbed
|
} // namespace mbed
|
||||||
#endif /* CELLULAR_TARGETS_TELIT_ME910_TELIT_ME910_H_ */
|
#endif /* CELLULAR_TARGETS_TELIT_ME910_TELIT_ME910_H_ */
|
||||||
|
|
|
@ -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 */
|
|
@ -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_
|
|
@ -17,6 +17,14 @@
|
||||||
"help": "CTS pin for serial connection",
|
"help": "CTS pin for serial connection",
|
||||||
"value": null
|
"value": null
|
||||||
},
|
},
|
||||||
|
"pwr": {
|
||||||
|
"help": "Power control pin",
|
||||||
|
"value": null
|
||||||
|
},
|
||||||
|
"polarity": {
|
||||||
|
"help": "Pin polarity, 1 = Active high, 0 = Active low",
|
||||||
|
"value": null
|
||||||
|
},
|
||||||
"baudrate" : {
|
"baudrate" : {
|
||||||
"help": "Serial connection baud rate",
|
"help": "Serial connection baud rate",
|
||||||
"value": 115200
|
"value": 115200
|
||||||
|
|
Loading…
Reference in New Issue