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) 00064 { 00065 _at.lock(); 00066 _at.cmd_start("AT+CFUN="); 00067 _at.write_int(func_level); 00068 _at.cmd_stop(); 00069 _at.resp_start(); 00070 _at.resp_stop(); 00071 return _at.unlock_return_error(); 00072 } 00073 00074 nsapi_error_t AT_CellularPower::reset() 00075 { 00076 _at.lock(); 00077 _at.cmd_start("AT+CFUN=");// reset to full power levels 00078 _at.write_int(1); 00079 _at.write_int(1); 00080 _at.cmd_stop(); 00081 _at.resp_start(); 00082 _at.resp_stop(); 00083 return _at.unlock_return_error(); 00084 } 00085 00086 nsapi_error_t AT_CellularPower::opt_power_save_mode(int periodic_time, int active_time) 00087 { 00088 _at.lock(); 00089 00090 if (periodic_time == 0 && active_time == 0) { 00091 // disable PSM 00092 _at.cmd_start("AT+CPSMS="); 00093 _at.write_int(0); 00094 _at.cmd_stop(); 00095 _at.resp_start(); 00096 _at.resp_stop(); 00097 } else { 00098 /** 00099 Table 10.5.163a/3GPP TS 24.008: GPRS Timer 3 information element 00100 00101 Bits 5 to 1 represent the binary coded timer value. 00102 00103 Bits 6 to 8 defines the timer value unit for the GPRS timer as follows: 00104 8 7 6 00105 0 0 0 value is incremented in multiples of 10 minutes 00106 0 0 1 value is incremented in multiples of 1 hour 00107 0 1 0 value is incremented in multiples of 10 hours 00108 0 1 1 value is incremented in multiples of 2 seconds 00109 1 0 0 value is incremented in multiples of 30 seconds 00110 1 0 1 value is incremented in multiples of 1 minute 00111 1 1 0 value is incremented in multiples of 320 hours (NOTE 1) 00112 1 1 1 value indicates that the timer is deactivated (NOTE 2). 00113 */ 00114 char pt[8+1];// timer value encoded as 3GPP IE 00115 const int ie_value_max = 0x1f; 00116 uint32_t periodic_timer = 0; 00117 if (periodic_time <= 2*ie_value_max) { // multiples of 2 seconds 00118 periodic_timer = periodic_time/2; 00119 strcpy(pt, "01100000"); 00120 } else { 00121 if (periodic_time <= 30*ie_value_max) { // multiples of 30 seconds 00122 periodic_timer = periodic_time/30; 00123 strcpy(pt, "10000000"); 00124 } else { 00125 if (periodic_time <= 60*ie_value_max) { // multiples of 1 minute 00126 periodic_timer = periodic_time/60; 00127 strcpy(pt, "10100000"); 00128 } else { 00129 if (periodic_time <= 10*60*ie_value_max) { // multiples of 10 minutes 00130 periodic_timer = periodic_time/(10*60); 00131 strcpy(pt, "00000000"); 00132 } else { 00133 if (periodic_time <= 60*60*ie_value_max) { // multiples of 1 hour 00134 periodic_timer = periodic_time/(60*60); 00135 strcpy(pt, "00100000"); 00136 } else { 00137 if (periodic_time <= 10*60*60*ie_value_max) { // multiples of 10 hours 00138 periodic_timer = periodic_time/(10*60*60); 00139 strcpy(pt, "01000000"); 00140 } else { // multiples of 320 hours 00141 int t = periodic_time / (320*60*60); 00142 if (t > ie_value_max) { 00143 t = ie_value_max; 00144 } 00145 periodic_timer = t; 00146 strcpy(pt, "11000000"); 00147 } 00148 } 00149 } 00150 } 00151 } 00152 } 00153 00154 uint_to_binary_str(periodic_timer, &pt[3], sizeof(pt)-3, PSMTimerBits); 00155 pt[8] = '\0'; 00156 00157 /** 00158 Table 10.5.172/3GPP TS 24.008: GPRS Timer information element 00159 00160 Bits 5 to 1 represent the binary coded timer value. 00161 00162 Bits 6 to 8 defines the timer value unit for the GPRS timer as follows: 00163 00164 8 7 6 00165 0 0 0 value is incremented in multiples of 2 seconds 00166 0 0 1 value is incremented in multiples of 1 minute 00167 0 1 0 value is incremented in multiples of decihours 00168 1 1 1 value indicates that the timer is deactivated. 00169 00170 Other values shall be interpreted as multiples of 1 minute in this version of the protocol. 00171 */ 00172 char at[8+1]; 00173 uint32_t active_timer; // timer value encoded as 3GPP IE 00174 if (active_time <= 2*ie_value_max) { // multiples of 2 seconds 00175 active_timer = active_time/2; 00176 strcpy(at, "00000000"); 00177 } else { 00178 if (active_time <= 60*ie_value_max) { // multiples of 1 minute 00179 active_timer = (1<<5) | (active_time/60); 00180 strcpy(at, "00100000"); 00181 } else { // multiples of decihours 00182 int t = active_time / (6*60); 00183 if (t > ie_value_max) { 00184 t = ie_value_max; 00185 } 00186 active_timer = t; 00187 strcpy(at, "01000000"); 00188 } 00189 } 00190 00191 uint_to_binary_str(active_timer, &at[3], sizeof(at)-3, PSMTimerBits); 00192 pt[8] = '\0'; 00193 00194 // request for both GPRS and LTE 00195 _at.cmd_start("AT+CPSMS="); 00196 _at.write_int(1); 00197 _at.write_string(pt); 00198 _at.write_string(at); 00199 _at.write_string(pt); 00200 _at.write_string(at); 00201 _at.cmd_stop(); 00202 _at.resp_start(); 00203 _at.resp_stop(); 00204 00205 00206 if (_at.get_last_error() != NSAPI_ERROR_OK ) { 00207 tr_warn("Power save mode not enabled!"); 00208 } else { 00209 // network may not agree with power save options but 00210 // that should be fine as timeout is not longer than requested 00211 } 00212 } 00213 00214 return _at.unlock_return_error(); 00215 } 00216 00217 nsapi_error_t AT_CellularPower::opt_receive_period(int mode, EDRXAccessTechnology act_type, uint8_t edrx_value) 00218 { 00219 char edrx[5]; 00220 uint_to_binary_str(edrx_value, edrx, 5, 4); 00221 edrx[4] = '\0'; 00222 00223 _at.lock(); 00224 00225 _at.cmd_start("AT+CEDRXS="); 00226 _at.write_int(mode); 00227 _at.write_int(act_type); 00228 _at.write_string(edrx); 00229 _at.cmd_stop(); 00230 _at.resp_start(); 00231 _at.resp_stop(); 00232 00233 return _at.unlock_return_error(); 00234 } 00235 00236 nsapi_error_t AT_CellularPower::set_device_ready_urc_cb(mbed::Callback<void()> callback) 00237 { 00238 return NSAPI_ERROR_UNSUPPORTED ; 00239 } 00240 00241 void AT_CellularPower::remove_device_ready_urc_cb(mbed::Callback<void()> callback) 00242 { 00243 }
Generated on Tue Jul 12 2022 12:32:20 by
