atsamd: SPI IdleLow does not IdleLow

I am currently trying to drive the Circuit Playground’s Neopixels using SPI. For doing so @david-sawatzke started writing an experimental crate. However, while trying to use it, I noticed the first pixel to always display #008000 instead of #000000. As we were able to determine with a logic-analyzer, the reason is that the SPI is IdleHigh and this is being interpreted as the first bit being one (ws2812 uses green-red-blue). My code:

let mut peripherals = Peripherals::take().unwrap();
let core = CorePeripherals::take().unwrap();
let mut clocks = GenericClockController::with_internal_32kosc(
    peripherals.GCLK,
    &mut peripherals.PM,
    &mut peripherals.SYSCTRL,
    &mut peripherals.NVMCTRL,
);
let mut pins = hal::Pins::new(peripherals.PORT);

let spi_pinout = hal::sercom::SPI5Pinout::Dipo2Dopo2 {
    miso: hal::sercom::Sercom5Pad2::pb0(pins.foo, &mut pins.port),
    mosi: hal::sercom::Sercom5Pad3::pb23(pins.neopixel, &mut pins.port),
    sck:  hal::sercom::Sercom5Pad1::pb17(pins.bar, &mut pins.port),
};

let gclk = clocks.gclk0();
let spi = hal::sercom::SPIMaster5::new(
    &clocks.sercom5_core(&gclk).unwrap(),
    3_000_000.hz(),
    embedded_hal::spi::Mode {
        polarity: embedded_hal::spi::Polarity::IdleLow,
        phase: embedded_hal::spi::Phase::CaptureOnFirstTransition,
    },
    peripherals.SERCOM5,
    &mut peripherals.PM,
    spi_pinout,
);

let mut ws = ws2812_spi::Ws2812::new(spi);

(The pins pins.foo and pins.bar are PB0 and PB17 respectively, I just added them to get the SPI peripheral working …)

Is there something wrong on my side or is this an issue in the hal?

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 17 (17 by maintainers)

Most upvoted comments

Yes, rust-embedded does this right: Clock Polarity

I guess, @david-sawatzke and me were just too tired at congress to notice 😛

capture_ws2812.gz (sigrok session file, rename to *.sr)

This is a sample capture from a trinket m0 with this sample program and this spi mode. This looks similar to the capture on the playground and also shows the same issue of the mosi line being high while idle.