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