Search code examples
c++cembeddedgpiospi

How can I get SPI SCK line to idle low without wasting current with a pulldown resistor?


I am using the STM32L475 MCU and am using SPI to communicate with an SD card.

When I configure the SPI SCK GPIO pin, I configure it as Alternate Function SPI in PushPull mode. I set the ClockPolarity to be idle low, which would make me think that the SCK line would remain low when inactive, but this is not the case. Instead, the SCK line idles high until SPI communications are started. This means that if I do a SPI write and subsequent read, an extra clock pulse is triggered, throwing off my communications.

The only way I found to be able to fix this is to further configure the GPIO pin to have a pull-down resistor, but this seems to me like it will be wasteful in terms of current draw. Configuring the pin as open-drain doesn't do the trick either, since I need to add a pull-up in that case anyway. Finally, I have tried writing to the GPIO pin's output register for the SCK pin and setting it to be low, but this does not change anything.

It seems to me like my only option is to place a pull-down resistor on a push-pull pin and constantly waste current in order to have the SCK line stay low. I was wondering if this was the normal solution that people used for SPI communications? I can't imagine that it is.


Solution

  • CPOL is the 1st bit of SPIx_CR1, controlling the idle state of CLK pin of a specific SPI. So if you want to remain SCK pin in low state when idle, try:

    SPI1->CR1 &= 0xFFFE;
    

    You can also configure the clock polarity in STM32CubeMX: screenshot.

    I haven't try these by myself, but according to the official document, these two method should work. Official STM32L47xxx Reference

    42.4.6 Communication formats
      Clock phase and polarity controls Four possible timing relationships may be chosen by software, using the CPOL and CPHA bits in the SPIx_CR1 register. The CPOL (clock polarity) bit controls the idle state value of the clock when no data is being transferred. This bit affects both master and slave modes. If CPOL is reset, the SCK pin has a low-level idle state. If CPOL is set, the SCK pin has a high-level idle state.
    ...
    Bit 1 CPOL: Clock polarity
    0. CK to 0 when idle
    1: CK to 1 when idle
    Note: This bit should not be changed when communication is ongoing.
    This bit is not used in SPI TI mode except the case when CRC is applied at TI mode.