Example program demonstrating proper powering down of Telit radio and putting the processor into STOP mode.
Dependencies: WakeUp mbed mtsas SpiFlash25
Fork of Dragonfly_Cellular_Ping_Example by
main.cpp
00001 /** Dragonfly Cellular Low Power Example 00002 * This program will run forever doing the following 00003 * bring up the cellular link 00004 * ping Google's DNS server 00005 * properly power off the radio 00006 * go to sleep 00007 * 00008 * There are two methods for properly powering off the cellular radio 00009 * 1) Software shutdown 00010 * - use Cellular::sendBasicCommand() to issue AT#SHDN to the radio and make sure it is successful 00011 * - poll vdd1_8_mon - when the radio powers off this line will go to 0 (at least 10s after AT#SHDN) 00012 * - drop the radio_reset line to 0 (pin PC_13) so the radio control chip doesn't attempt to restart the radio 00013 * - (optional) drop the radio_pwr line to 0 00014 * + this eliminates all current draw from the radio when it is powered off but increases the time it takes to reconnect to the network 00015 * 2) Hardware shutdown 00016 * - drop the radio_reset line to 0 (pin PC_13) so the radio control chip doesn't attempt to restart the radio 00017 * - poll vdd1_8_mon - when the radio powers off this line will go to 0 (at least 10s after radio_reset was dropped) 00018 * - (optional) drop the radio_pwr line to 0 00019 * + this eliminates all current draw from the radio when it is powered off but increases the time it takes to reconnect to the network 00020 * 00021 * NOTE: This example changes the baud rate of the debug port to 115200 baud! 00022 * NOTE: A SIM card is required for GSM radios to connect to the network! 00023 * NOTE: CDMA cellular radios need to be provisioned before use! 00024 */ 00025 00026 #include "mbed.h" 00027 #include "mtsas.h" 00028 #include "WakeUp.h" 00029 #include "SpiFlash25.h" 00030 00031 // This line controls the regulator's battery charger. 00032 // BC_NCE = 0 enables the battery charger 00033 // BC_NCE = 1 disables the battery charger 00034 DigitalOut bc_nce(PB_2); 00035 00036 // These lines are used to control the maximum current draw of the regulator 00037 // | 100mA mode | 500mA mode| 1A mode | 00038 // -------------------------------------------- 00039 // BC_EN1 | 0 | 1 | 0 | 00040 // BC_EN2 | 0 | 0 | 1 | 00041 // -------------------------------------------- 00042 // Default is 1A mode 00043 DigitalOut bc_en1(PC_14, 0); 00044 DigitalOut bc_en2(PC_15, 1); 00045 00046 // This line is used to reset or perform a HW shutdown the radio 00047 // Set it low and keep it low to perform a HW shutdown 00048 // Toggle it low and then high again to reset the radio 00049 DigitalOut radio_reset(PC_13, 1); 00050 00051 // This line controls power to the radio 00052 // It should only be dropped after the radio has been powered off via the radio_reset line or AT#SHDN command to reduce all current consumption from the radio 00053 DigitalOut radio_pwr(PC_3, 1); 00054 00055 // This line is 1 when the radio has sufficient power 00056 // It goes to 0 after the radio has successfully shut down 00057 DigitalIn vdd1_8_mon(PC_5); 00058 00059 SpiFlash25 flash(SPI_MOSI, SPI_MISO, SPI_SCK, SPI_CS1); 00060 00061 bool init_mtsas(); 00062 void enterStopMode(const uint32_t interval); 00063 00064 // The MTSSerialFlowControl object represents the physical serial link between the processor and the cellular radio. 00065 mts::MTSSerialFlowControl* io; 00066 // The Cellular object represents the cellular radio. 00067 mts::Cellular* radio; 00068 00069 // An APN is required for GSM radios. 00070 static const char apn[] = ""; 00071 00072 bool radio_ok = false; 00073 00074 int main() { 00075 // Disable the battery charger unless a battery is attached. 00076 bc_nce = 1; 00077 00078 uint32_t sleep_time = 10; 00079 Timer tmr; 00080 00081 // Change the baud rate of the debug port from the default 9600 to 115200. 00082 Serial debug(USBTX, USBRX); 00083 debug.baud(115200); 00084 00085 //Sets the log level to INFO, higher log levels produce more log output. 00086 //Possible levels: NONE, FATAL, ERROR, WARNING, INFO, DEBUG, TRACE 00087 mts::MTSLog::setLogLevel(mts::MTSLog::INFO_LEVEL); 00088 radio_ok = init_mtsas(); 00089 if (! radio_ok) { 00090 while (true) { 00091 logError("failed to initialize cellular radio"); 00092 wait(1); 00093 } 00094 } 00095 00096 while (true) { 00097 logInfo("changing regulator to 1A mode"); 00098 bc_en1 = 0; 00099 bc_en2 = 1; 00100 logInfo("waking up the SPI flash"); 00101 flash.wakeup(); 00102 logInfo("powering on radio"); 00103 radio_pwr = 1; 00104 radio_reset = 1; 00105 int tries = 0; 00106 00107 while (radio->sendBasicCommand("AT", 1000) != MTS_SUCCESS) { 00108 wait(1); 00109 tries++; 00110 if (tries % 25 == 0) { 00111 logWarning("no response from radio after 25 tries (total tries %d) - resetting radio", tries); 00112 radio_reset = 0; 00113 wait_ms(10); 00114 radio_reset = 1; 00115 } 00116 printf("."); 00117 } 00118 printf("\r\n"); 00119 00120 logInfo("setting APN"); 00121 if (radio->setApn(apn) != MTS_SUCCESS) 00122 logError("failed to set APN to \"%s\"", apn); 00123 logInfo("bringing up the link"); 00124 if (! radio->connect()) { 00125 logError("failed to bring up the link"); 00126 } else { 00127 for (int i = 0; i < 10; i++) { 00128 logInfo("pinging"); 00129 if (! radio->ping("www.google.com")) 00130 logError("failed to ping"); 00131 else 00132 logInfo("ping succeeded"); 00133 } 00134 logInfo("finished - bringing down link"); 00135 radio->disconnect(); 00136 } 00137 00138 // power down the radio 00139 logInfo("powering down radio"); 00140 radio_reset = 0; 00141 logInfo("waiting up to 30s for vdd1_8_mon to go low"); 00142 tmr.reset(); 00143 tmr.start(); 00144 // wait up to 30s for the radio to shut down 00145 while (vdd1_8_mon != 0 && tmr.read() < 30) { 00146 wait(1); 00147 printf("."); 00148 } 00149 tmr.stop(); 00150 printf("\r\n"); 00151 if (vdd1_8_mon != 0 && tmr.read() >= 30) { 00152 logError("radio did not shut down! aborting iteration"); 00153 continue; 00154 } 00155 00156 logInfo("radio powered off after %fs", tmr.read()); 00157 radio_pwr = 0; 00158 logInfo("putting the SPI flash in deep power down"); 00159 flash.deep_power_down(); 00160 logInfo("putting regulator in 100mA mode"); 00161 bc_en1 = 0; 00162 bc_en2 = 0; 00163 00164 logInfo("going to sleep for %lu seconds", sleep_time); 00165 enterStopMode(sleep_time); 00166 } 00167 00168 return 0; 00169 } 00170 00171 bool init_mtsas() { 00172 io = new mts::MTSSerialFlowControl(RADIO_TX, RADIO_RX, RADIO_RTS, RADIO_CTS); 00173 if (! io) 00174 return false; 00175 00176 // radio default baud rate is 115200 00177 io->baud(115200); 00178 radio = mts::CellularFactory::create(io); 00179 if (! radio) 00180 return false; 00181 00182 // Transport must be set properly before any TCPSocketConnection or UDPSocket objects are created 00183 Transport::setTransport(radio); 00184 00185 return true; 00186 } 00187 00188 #define RTC_ALARMA_DISABLE() do { \ 00189 RTC->ISR &= ~RTC_ISR_ALRAF; \ 00190 RTC->WPR = 0xCA; \ 00191 RTC->WPR = 0x53; \ 00192 RTC->CR &= ~(RTC_CR_ALRAE | RTC_CR_ALRAIE); \ 00193 RTC->WPR = 0xFF; \ 00194 } while (0) 00195 00196 void enterStopMode(const uint32_t interval) { 00197 // disable ADC - it can consume power in stop mode 00198 ADC1->CR2 &= ~ADC_CR2_ADON; 00199 00200 // enable debugging during stop mode 00201 HAL_EnableDBGStopMode(); 00202 00203 // put regulators into low-power mode 00204 HAL_PWREx_EnableMainRegulatorLowVoltage(); 00205 HAL_PWREx_EnableLowRegulatorLowVoltage(); 00206 00207 // power down flash 00208 HAL_PWREx_EnableFlashPowerDown(); 00209 00210 // configure RTC Alarm A to wake the device up 00211 WakeUp::set(interval); 00212 00213 // make sure wakeup flag is cleared 00214 PWR->CR |= PWR_CR_CWUF; 00215 00216 logInfo("entering stop mode %08x", RTC->ISR); 00217 fflush(stdout); 00218 00219 // enter stop mode - don't execute past here until woken up 00220 HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI); 00221 00222 // HSI (High Speed Internal) oscillator is selected when coming out of stop mode - set up clocking 00223 SetSysClock(); 00224 00225 // disable RTC alarm A and RTC alarm A interrupt 00226 RTC_ALARMA_DISABLE(); 00227 00228 // clear wakeup flag in power control register 00229 PWR->CR |= PWR_CR_CWUF; 00230 00231 // put regulators back into to full-power mode 00232 HAL_PWREx_DisableMainRegulatorLowVoltage(); 00233 HAL_PWREx_DisableLowRegulatorLowVoltage(); 00234 00235 // turn the flash back on 00236 HAL_PWREx_DisableFlashPowerDown(); 00237 00238 // enable the ADC 00239 ADC1->CR2 |= ADC_CR2_ADON; 00240 00241 // disable debugging during stop mode 00242 HAL_DisableDBGStopMode(); 00243 }
Generated on Tue Jul 12 2022 18:07:56 by 1.7.2