sparkfun / Arduino_Apollo3

Arduino core to support the Apollo3 microcontroller from Ambiq Micro
83 stars 37 forks source link

GPIO pin and current consumption odd behavior #439

Open derekpickell opened 2 years ago

derekpickell commented 2 years ago

Hi All,

Found a bug experimenting with the Sparkfun MMDLCB with v2 of the Apollo3 Core.

Issue: Essentially, when disabling onboard LDOs, I measure an increase in current consumption, not a decrease as expected (as in v1.2.3). These LDOs have an enable pin that when driven low should cut all power downstream to peripherals, such as SD sockets, which is what I was experimenting with), but this is no longer the case.

I'm attaching my code below where I observed this behavior. Opening this issue following posting to sparkfun forums here.

Thanks!

#define PIN_SD_POWER      33  // G1 - Drive low to turn off SD/Perhipherals
#define SD_CONFIG SdSpiConfig(41, SHARED_SPI, SD_SCK_MHZ(24))

#include <SdFat.h>
#include <SPI.h> 
SdFs sd;  

void setup() {
  //Serial.begin(115200);
  digitalWrite(PIN_SD_POWER, LOW);
  pinMode(LED_BUILTIN, OUTPUT);
  delay(2000);

}

void loop() {
  // TURN PERIPHERAL uSD ON
  SPI.begin();
  digitalWrite(PIN_SD_POWER, HIGH);
  digitalWrite(LED_BUILTIN, HIGH);
  delay(100);
  if (!sd.begin(SD_CONFIG)) { 
      while (1);
  }

  // TURN PERIPHERAL uSD OFF
  delay(5000);
  SPI.end();
  digitalWrite(PIN_SD_POWER, LOW);
  digitalWrite(LED_BUILTIN, LOW);
  delay(5000);

}
adamgarbo commented 2 years ago

Hi folks,

Just to note that I also tested the MMDLCB and can confirm the high quiescent draw when the LDO that controls power to the microSD is disabled. @derekpickell, as Paul mentioned on the forums you should have a pinMode(PIN_SD_POWER, OUTPUT) declaration in your setup, but I still experienced the high current draw with it set correctly.

@PaulZC did you notice any jump in the quiescent draw of the OLA after you migrated to v2.x of the Apollo3 Core?

Cheers, Adam

PaulZC commented 2 years ago

Hi Adam ( @adamgarbo ),

I did indeed... On OpenLog Artemis:

https://github.com/sparkfun/OpenLog_Artemis/blob/c5c2947dad2f7199718a62bf57462e3db2965dcf/Firmware/OpenLog_Artemis/OpenLog_Artemis.ino#L109

I haven't had time to investigate further...

Cheers, Paul

PaulZC commented 2 years ago

PS. your Forum Post link is broken. ;-)

adamgarbo commented 2 years ago

Thanks, @PaulZC!

The other Paul provided some additional information regarding the changes to SPI in v2.x on the forums. I'm seeing 18 mA when the LDO on the MMDLCB is disabled, while @derekpickell is seeing ~200 mA. I'm wondering if this is a different issue than with the OLA.

Cheers, Adam

paulvha commented 2 years ago

Finally got some time to look into this, and have found the root cause.

Test1 : When you only switch ON and OFF the LDO (pin 33), the current usage is dropping (to 3.5mA in my case) when OFF. (pin 3 is low) Test2 : When you add SPI.begin() and SPI.end(), to test1, the current usage is dropping when OFF. Test3 : When you add sd.begin() and sd.end() to test2, now the current is 26mA increasing when OFF. Confirmed that the G1- 3v3 is really ZERO VOLT.

I also have an external SD card reader. Also from Sparkfun (DEV-13743) that I connected to the header. Instead of CS being 41 select 16 pin (HEADER-CS). I have used the same uSD and confirmed with a sketch that I can access and read the SD card.

MMDLCB      uSD
==============
GND         GND
CS          CS
CIPO        D0
COPI        D1
SCK         SCK
G1-3v3      VCC

Test 4: Same test as test 3, and the current is dropping off !!!!

Looking at the LDO specification it has 60-ohm discharge resistors which are only set with LDO ENABLE is low. So it could draw current in low, but where is the positive input coming from that leak through the card? The 26mA in my case is caused by a resistor 126 ohm.

Is it leak current coming through the card? YES, somehow... Test5 : When removing the SD card in the situation of Test3, now the current drops to the lower level.

Test 6: Setting the card IDLE I changed the Sdfat library to include a CMD0 (set the card idle) before SPI.end(). Same condition as test 3 and same result as test3, 26 mA current in the off state

After a number of tests, I could prove that if the LDO is turned off (pin 33 LOW) and EITHER CS is HIGH or COPI is HIGH, it will cause the high current following from these lines through the micro SD card, through the discharge resistors of the LDO. By setting the pins in tristate you can solve/bypass this issue. No impact from CIPO (as one would expect), but also SCK was not having an impact. Still, I would advise following the same solution as for CS and COPI. Might it was my card. Also depending on the card type, vendor etc, you might see different current when LDO is turned off.

Unlike V2, in V1.2.3 the IOM and pins are really reset.

Use the sketch in the following way :

#define PIN_SD_POWER    33  // G1 - Drive low to turn off SD/Perhipherals
#define COPI_IOM3       38
#define CS_IOM3         41
#define SCK_IOM3        42

#define SD_CONFIG SdSpiConfig(CS_IOM3, SHARED_SPI, SD_SCK_MHZ(24))

#include <SdFat.h>
#include <SPI.h> 
SdFs sd;  

void setup() {
  //Serial.begin(115200);
  digitalWrite(PIN_SD_POWER, LOW);
  pinMode(LED_BUILTIN, OUTPUT);
  delay(2000);

}

void loop() {
  // TURN PERIPHERAL uSD ON
  SPI.begin();
  digitalWrite(PIN_SD_POWER, HIGH);
  digitalWrite(LED_BUILTIN, HIGH);
  delay(100);
  if (!sd.begin(SD_CONFIG)) { 
      while (1);
  }

  // TURN PERIPHERAL uSD OFF
  delay(5000);
  sd.end();
  SPI.end();

  /* Set to tristate so these pins are now floating and
   * not causing current flow   */
  am_hal_gpio_pinconfig(CS_IOM3, g_AM_HAL_GPIO_TRISTATE);
  am_hal_gpio_pinconfig(COPI_IOM3, g_AM_HAL_GPIO_TRISTATE);
  am_hal_gpio_pinconfig(SCK_IOM3, g_AM_HAL_GPIO_TRISTATE);

  digitalWrite(PIN_SD_POWER, LOW);
  digitalWrite(LED_BUILTIN, LOW);
  delay(5000);

  /* reset the pins to what is needed for SPI. Given the construction
   * with MBED you will have to do that manually  */
  pin_config(PinName(COPI_IOM3), g_AM_BSP_GPIO_SPI_SDO);
  pin_config(PinName(SCK_IOM3), g_AM_BSP_GPIO_SPI_SCK); 
  pinMode(CS_IOM3, OUTPUT);
  digitalWrite(CS_IOM3, HIGH); // make sure card is NOT selected when power is applied
}
Wenn0101 commented 2 years ago

Hey @paulvha, reading thru this, it sounds like if the core properly de-inited the pins, there wouldn't be a problem here.

So I need to find a way to properly implement setting this pins to tristate in SPI.end. This seems related to your recent PR (which I thought I merged but I curiously don't see in the dev branch for some reason). Perhaps if the IOM was properly de-inited, this could also solve the problem. I'll see what testing I can do here.

paulvha commented 2 years ago

hi Kyle,

Yes, indeed.

However, it is half the solution. We should actually do a proper de-init and shutdown of the IOM for both SPI and I2C. I worked on an OpenLog issue recently with I2C. https://github.com/sparkfun/OpenLog_Artemis/issues/117. Many people like to use the low power capabilities of the Apollo3 chip. If you look at the issue that PaulCZ posted before in this issue. Much higher pwer consumption in V2 compared to V1. The root cause is not the LDO, as Openlog uses a FET. But looking at the Openlog V2 code, it is not even trying to power off the IOM for SPI and I2C as Openlog will "hang" on wake-up.

With a couple of more changes, a complete solution could be possible. For I2C I have worked that out, I could spend a couple of hours this week to also find a similar solution for SPI. Have a look and let me know.

regards, Paul

Wenn0101 commented 2 years ago

Hey Paul,

This is great stuff! I admittedly haven't been monitoring the OLA issues, and it turns out that has been a mistake!

I think it is interesting you have to call the _deinit function explicitly. It was my impression (that I am now finding to probably be wrong) that MbedOS used some C++ wizardry to stitch the de-init functions in with the destructors, such that you could just delete the object to deinit it. It seems like the intention, but it looks like this has been an issue for a while and isn't changing. This certainly complicates the implementation.

-Kyle

paulvha commented 2 years ago

Hi Kyle,

Mbed constant reminds me of a remark from a marketing manager who I used to work with during my active career in IT:

The difference between us and competition? We know how to do it difficult!

Well, it at least is good to know we are not alone to understand what is happening (or not happening). Will take time later this week to better understand.

regards, Paul