The LMIC_shutdown() does nothing special, it just sets the chip to sleep mode (the default mode after any transmission), and cancels any callback.
LMIC_shutdown() results for me in the mentioned 0.5mA (not 0.5µA :-/ )
To clarify the way I measure: I do not measure the current through the 3.3V line to the RFM95, but measure the current for the whole setup: microcontroller + RFM95. That’s about 2µA with the RFM95 disconnected from ground (2µA is the current usage from the STM32 in DeepSleep mode) and 0.5mA with the RFM95 connected to ground.
Btw, it’s generally bad engineering practice to disconnect the ground of something you want to power off. This makes your device float and can potentially damage still connected in/outputs of the device itself or other connected devices. It also leads to current leaking through this connected I/O.
On most micro’s and all CMOS I/O, leaving input pins to float consumes quite a lot of power (relatively speaking). You need to pull them up to VCC or down to GND. Output pins can safely be left floating.
Pullups do not consume power if the ports or pins they are connected to are tristated or configured as an input while sleeping.
My case wasn’t with arduino-lmic, just bare SPI to RFM95 on mbed and nRF51, so I was in full control of GPIO and in my responsibility. But in your case, on arduino, something like INPUT PULLUP could be what you need. Give it a try.
The irony is that currently my Atmega setup works but the 21th century STM32 not
I discovered that with all pins floating (STM32 Standby mode: 2 μA) the RFM95 uses 0.39mA.
The fundamental problem is that the STM32 uses in STOP mode (GPIOs in last setting, all clocks stopped except wakeup timer) in default GPIO state 0.7 mA.
With all pins programmed to analog input (according to the STM manual the most power efficient state) 0.018 mA in the same STOP mode.
So I am currently trading reduced leakage through the RFM pins for a less efficient STM32 GPIO setting. Pulling NSS low drops the current from 0.7mA to 0.4mA so the SPI configuration is probably the root cause, but I have not found a configuration with lower usage than 0.4mA for the STM32 setup.
Perhaps additional external pull up resistors are indeed the only solution.
You’ve got yourself a real catch-22 there indeed. If you go for the analog input sleep option, using pull-ups will probably leak some current through the ADC input capacitor as well. Did you try setting all pins to digital input with internal pull-up OR digital output written low before going to sleep?
I use Freescale excuse me NXP Kinetis MK20 controllers, which are based on the same Cortex cores as the STM32, together with this excellent library for very satisfying results. The library saves the pin state, then puts all pins to output low and goes to sleep. When it wakes again, pin state is restored and the program continues as if nothing happened. The controller uses around 15µA during sleep.