I'm building a battery operated device and must shutoff MOSI pin during sleep because it leaks current through the SD card if I don't (about 400 µA).
Problem is, it won't stay off. I've looked at SPI documentation and as far as I know I just need to call spi.end()
then set pinmode to output and finally digitalWrite LOW. I observe with an oscilloscope that it does go low upon my asking it to but only for about 1 µs (actually it goes low twice within a 5 µs time period).
I've also tried manually setting the pin low using the PORT registers and the behavior is the same... see relevant code:
spi.end();
//pinMode(pin_MOSI, OUTPUT);
//digitalWrite(pin_MOSI, LOW);
//Both above (commented out) and below result in the same behavior -- pin does not stay LOW
DDRB |= B00100000; //set pin 5 as output
PORTB &= B11011111; //set output low for pin 5
delay(5000);
...As you can see there is a delay to ensure that it isn't being set high by some other code.
Is there some sort of SPI interrupt that automatically sets the pin high again?
Hardware details:
MCU: ATMEGA1284P; Programmer: Atmel-ICE
UPDATE (13-Mar-2019):
I didn't realize that SPI is implemented by Atmel in hardware directly (see datasheet page 105):
MOSI/PCINT13 – Port B, Bit 5 – MOSI: SPI Master Data output, Slave Data input for SPI channel. When the SPI0 is enabled as a slave, this pin is configured as an input regardless of the setting of DDB5. When the SPI is enabled as a master, the data direction of this pin is controlled by DDB5. When the pin is forced to be an input, the pull-up can still be controlled by the PORTB5 bit.
I am currently chasing down this latest information and will hopefully come to a resolution soon. I will post any progress.