Skip to content

SPI: SCLK polarity (CPOL) is inverted #1900

@maxgerhardt

Description

@maxgerhardt

Wikipedia says

grafik

so for CPOL = 0, the SCLK pin should idle LOW before and after a SPI transfer.

However, testing with

#include <Arduino.h>
#include <SPI.h>
static int _sck = 2;
static int _mosi = 3;
static int _miso = 4;
static int _cs = 5;

void setup() {
    SPI.setSCK(_sck);
    SPI.setTX(_mosi);
    SPI.setRX(_miso);
    SPI.setCS(_cs);
    SPI.begin(true /* HW CS */);
}

void loop() {
  SPI.beginTransaction(SPISettings(100000, MSBFIRST, SPI_MODE0));
  uint8_t value = 0xAA;
  SPI.transfer(value);
  SPI.endTransaction();
  delay(100);
}

I see

grafik

on GP2, 3, 4 and 5 respectively. This is exactly inverted, it idles HIGH. Wut?

The signal also looks exactly the same when using native Pico-SDK functions:

#include <Arduino.h>
#include <hardware/spi.h>
static int _sck = 2;
static int _mosi = 3;
static int _miso = 4;
static int _cs = 5;
static spi_inst_t* _spi = spi0;

void setup() {
  gpio_set_function(_sck, GPIO_FUNC_SPI);
  gpio_set_function(_mosi, GPIO_FUNC_SPI);
  gpio_set_function(_miso, GPIO_FUNC_SPI);
  gpio_set_function(_cs, GPIO_FUNC_SPI);

  spi_init(_spi, 100000);
  spi_set_format(_spi, 8, SPI_CPOL_0, SPI_CPHA_0, SPI_MSB_FIRST);
}

void loop() {
  uint8_t value = 0xAA;
  (void) spi_write_blocking(_spi, &value, sizeof(value));
  delay(100);
}

Note that changing to SPI_CPOL_1 in the above example will make the clock idle low. But no matter what, in my logic analyzer, I always have to select the opposite SPI mode / clock polarity than what I set in the code ot make decodable.

grafik

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions