Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
AT_CellularPower.cpp
00001 /* 00002 * Copyright (c) 2017, Arm Limited and affiliates. 00003 * SPDX-License-Identifier: Apache-2.0 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); 00006 * you may not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 */ 00017 00018 #include "AT_CellularPower.h" 00019 #include "CellularUtil.h" 00020 #include "CellularLog.h" 00021 #include "CellularTargets.h" 00022 #include "nsapi_types.h" 00023 00024 static const int PSMTimerBits = 5; 00025 00026 using namespace mbed_cellular_util; 00027 using namespace mbed; 00028 00029 AT_CellularPower::AT_CellularPower(ATHandler &at) : AT_CellularBase(at) 00030 { 00031 } 00032 00033 AT_CellularPower::~AT_CellularPower() 00034 { 00035 } 00036 00037 nsapi_error_t AT_CellularPower::on() 00038 { 00039 return NSAPI_ERROR_UNSUPPORTED ; 00040 } 00041 00042 nsapi_error_t AT_CellularPower::off() 00043 { 00044 return NSAPI_ERROR_UNSUPPORTED ; 00045 } 00046 00047 nsapi_error_t AT_CellularPower::set_at_mode() 00048 { 00049 _at.lock(); 00050 _at.flush(); 00051 _at.cmd_start("ATE0"); // echo off 00052 _at.cmd_stop(); 00053 _at.resp_start(); 00054 _at.resp_stop(); 00055 00056 _at.cmd_start("AT+CMEE=1"); // verbose responses 00057 _at.cmd_stop(); 00058 _at.resp_start(); 00059 _at.resp_stop(); 00060 return _at.unlock_return_error(); 00061 } 00062 00063 nsapi_error_t AT_CellularPower::set_power_level(int func_level, int do_reset) 00064 { 00065 _at.lock(); 00066 _at.cmd_start("AT+CFUN="); 00067 _at.write_int(func_level); 00068 _at.write_int(do_reset); 00069 _at.cmd_stop(); 00070 _at.resp_start(); 00071 _at.resp_stop(); 00072 return _at.unlock_return_error(); 00073 } 00074 00075 nsapi_error_t AT_CellularPower::reset() 00076 { 00077 _at.lock(); 00078 _at.cmd_start("AT+CFUN=");// reset to full power levels 00079 _at.write_int(1); 00080 _at.write_int(1); 00081 _at.cmd_stop(); 00082 _at.resp_start(); 00083 _at.resp_stop(); 00084 return _at.unlock_return_error(); 00085 } 00086 00087 nsapi_error_t AT_CellularPower::opt_power_save_mode(int periodic_time, int active_time) 00088 { 00089 _at.lock(); 00090 00091 if (periodic_time == 0 && active_time == 0) { 00092 // disable PSM 00093 _at.cmd_start("AT+CPSMS="); 00094 _at.write_int(0); 00095 _at.cmd_stop(); 00096 _at.resp_start(); 00097 _at.resp_stop(); 00098 } else { 00099 /** 00100 Table 10.5.163a/3GPP TS 24.008: GPRS Timer 3 information element 00101 00102 Bits 5 to 1 represent the binary coded timer value. 00103 00104 Bits 6 to 8 defines the timer value unit for the GPRS timer as follows: 00105 8 7 6 00106 0 0 0 value is incremented in multiples of 10 minutes 00107 0 0 1 value is incremented in multiples of 1 hour 00108 0 1 0 value is incremented in multiples of 10 hours 00109 0 1 1 value is incremented in multiples of 2 seconds 00110 1 0 0 value is incremented in multiples of 30 seconds 00111 1 0 1 value is incremented in multiples of 1 minute 00112 1 1 0 value is incremented in multiples of 320 hours (NOTE 1) 00113 1 1 1 value indicates that the timer is deactivated (NOTE 2). 00114 */ 00115 char pt[8 + 1]; // timer value encoded as 3GPP IE 00116 const int ie_value_max = 0x1f; 00117 uint32_t periodic_timer = 0; 00118 if (periodic_time <= 2 * ie_value_max) { // multiples of 2 seconds 00119 periodic_timer = periodic_time / 2; 00120 strcpy(pt, "01100000"); 00121 } else { 00122 if (periodic_time <= 30 * ie_value_max) { // multiples of 30 seconds 00123 periodic_timer = periodic_time / 30; 00124 strcpy(pt, "10000000"); 00125 } else { 00126 if (periodic_time <= 60 * ie_value_max) { // multiples of 1 minute 00127 periodic_timer = periodic_time / 60; 00128 strcpy(pt, "10100000"); 00129 } else { 00130 if (periodic_time <= 10 * 60 * ie_value_max) { // multiples of 10 minutes 00131 periodic_timer = periodic_time / (10 * 60); 00132 strcpy(pt, "00000000"); 00133 } else { 00134 if (periodic_time <= 60 * 60 * ie_value_max) { // multiples of 1 hour 00135 periodic_timer = periodic_time / (60 * 60); 00136 strcpy(pt, "00100000"); 00137 } else { 00138 if (periodic_time <= 10 * 60 * 60 * ie_value_max) { // multiples of 10 hours 00139 periodic_timer = periodic_time / (10 * 60 * 60); 00140 strcpy(pt, "01000000"); 00141 } else { // multiples of 320 hours 00142 int t = periodic_time / (320 * 60 * 60); 00143 if (t > ie_value_max) { 00144 t = ie_value_max; 00145 } 00146 periodic_timer = t; 00147 strcpy(pt, "11000000"); 00148 } 00149 } 00150 } 00151 } 00152 } 00153 } 00154 00155 uint_to_binary_str(periodic_timer, &pt[3], sizeof(pt) - 3, PSMTimerBits); 00156 pt[8] = '\0'; 00157 00158 /** 00159 Table 10.5.172/3GPP TS 24.008: GPRS Timer information element 00160 00161 Bits 5 to 1 represent the binary coded timer value. 00162 00163 Bits 6 to 8 defines the timer value unit for the GPRS timer as follows: 00164 00165 8 7 6 00166 0 0 0 value is incremented in multiples of 2 seconds 00167 0 0 1 value is incremented in multiples of 1 minute 00168 0 1 0 value is incremented in multiples of decihours 00169 1 1 1 value indicates that the timer is deactivated. 00170 00171 Other values shall be interpreted as multiples of 1 minute in this version of the protocol. 00172 */ 00173 char at[8 + 1]; 00174 uint32_t active_timer; // timer value encoded as 3GPP IE 00175 if (active_time <= 2 * ie_value_max) { // multiples of 2 seconds 00176 active_timer = active_time / 2; 00177 strcpy(at, "00000000"); 00178 } else { 00179 if (active_time <= 60 * ie_value_max) { // multiples of 1 minute 00180 active_timer = (1 << 5) | (active_time / 60); 00181 strcpy(at, "00100000"); 00182 } else { // multiples of decihours 00183 int t = active_time / (6 * 60); 00184 if (t > ie_value_max) { 00185 t = ie_value_max; 00186 } 00187 active_timer = t; 00188 strcpy(at, "01000000"); 00189 } 00190 } 00191 00192 uint_to_binary_str(active_timer, &at[3], sizeof(at) - 3, PSMTimerBits); 00193 at[8] = '\0'; 00194 00195 // request for both GPRS and LTE 00196 _at.cmd_start("AT+CPSMS="); 00197 _at.write_int(1); 00198 _at.write_string(pt); 00199 _at.write_string(at); 00200 _at.write_string(pt); 00201 _at.write_string(at); 00202 _at.cmd_stop(); 00203 _at.resp_start(); 00204 _at.resp_stop(); 00205 00206 00207 if (_at.get_last_error() != NSAPI_ERROR_OK ) { 00208 tr_warn("Power save mode not enabled!"); 00209 } else { 00210 // network may not agree with power save options but 00211 // that should be fine as timeout is not longer than requested 00212 } 00213 } 00214 00215 return _at.unlock_return_error(); 00216 } 00217 00218 nsapi_error_t AT_CellularPower::opt_receive_period(int mode, EDRXAccessTechnology act_type, uint8_t edrx_value) 00219 { 00220 char edrx[5]; 00221 uint_to_binary_str(edrx_value, edrx, 5, 4); 00222 edrx[4] = '\0'; 00223 00224 _at.lock(); 00225 00226 _at.cmd_start("AT+CEDRXS="); 00227 _at.write_int(mode); 00228 _at.write_int(act_type); 00229 _at.write_string(edrx); 00230 _at.cmd_stop(); 00231 _at.resp_start(); 00232 _at.resp_stop(); 00233 00234 return _at.unlock_return_error(); 00235 } 00236 00237 nsapi_error_t AT_CellularPower::is_device_ready() 00238 { 00239 _at.lock(); 00240 _at.cmd_start("AT"); 00241 _at.cmd_stop(); 00242 _at.resp_start(); 00243 _at.resp_stop(); 00244 00245 // we need to do this twice because for example after data mode the first 'AT' command will give modem a 00246 // stimulus that we are back to command mode. 00247 _at.clear_error(); 00248 _at.cmd_start("AT"); 00249 _at.cmd_stop(); 00250 _at.resp_start(); 00251 _at.resp_stop(); 00252 00253 return _at.unlock_return_error(); 00254 } 00255 00256 nsapi_error_t AT_CellularPower::set_device_ready_urc_cb(mbed::Callback<void()> callback) 00257 { 00258 return NSAPI_ERROR_UNSUPPORTED ; 00259 } 00260 00261 void AT_CellularPower::remove_device_ready_urc_cb(mbed::Callback<void()> callback) 00262 { 00263 }
Generated on Tue Aug 9 2022 00:37:03 by
