Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SPI - odd sequence at end of data #553

Open
stephenhensley opened this issue Dec 13, 2022 · 3 comments
Open

SPI - odd sequence at end of data #553

stephenhensley opened this issue Dec 13, 2022 · 3 comments

Comments

@stephenhensley
Copy link
Collaborator

    @stephenhensley 

My current issue/findings:

I have the SM rev 3, and with the current libDaisy and BOOT_SRAM the display stays black when I control it with the hardware SPI transport. I only got this to work with SpiHandle::Config::BaudPrescaler::PS_128 and if I used the ScopedIrqBlocker around the display.Update(). As far as I can remember, the ScopedIrqBlocker was only necessary when executing hw.StartAudio(). I also examined the whole thing with a LogicAnlyser and found that at the end the SPI sequence is somethig strange with the clock (at the end there is an unnecessary clock change).

image

I also noticed that the SPI ports D9, D8 are read by the ADC. I have removed these testwise from the ADC initialization (without success).
After some googling I found the stm32h7 errata, where it says that there are SPI problems at high clock rates. After further investigation I found out that the whole clock configuration in the System::Init() is skipped in the BOOT_SRAM case, or probably done in the bootloader (closed source).

Maybe there is still some other solution, but I thought that the SoftwareSPI implementation might be useful in general.

@GregBurns - Well - I recently started using the internal MidiUSBHandler - but i think it didn't work otherwise either.

Originally posted by @eh2k in #551 (comment)

@stephenhensley
Copy link
Collaborator Author

@eh2k Does the odd sequence at the end happen when building your app for the system bootloader instead of with BOOT_SRAM, or is the issue dependent on it being a bootloader application?

@eh2k
Copy link
Contributor

eh2k commented Dec 15, 2022

@stephenhensley

yes - the problem also occurs with APP_TYPE==BOOT_NONE (flash mode).

Here is my test program where the display just works:

  • ScopedIrqBlocker is mandatory when hw.StartAudio was executed
  • baud_prescaler >= 128 otherwise black display or flicker
  • tested with 2 different displays (ssd1306 and sh1106) - same issue
#include "daisy_patch_sm.h"
#include "dev/oled_ssd130x.h"

using namespace daisy;
using namespace patch_sm;

DaisyPatchSM hw;

using namespace daisy;
using namespace daisy::patch_sm;

using MyDisplay = OledDisplay<SSD130x4WireSpi128x64Driver>;
MyDisplay display;

void AudioCallback(AudioHandle::InputBuffer in,
                   AudioHandle::OutputBuffer out,
                   size_t size)
{
    //
}

int main(void)
{
    // Initialize the hardware
    hw.Init();
    hw.StartAudio(AudioCallback);

    MyDisplay::Config display_config;

    SpiHandle::Config& spi_conf = display_config.driver_config.transport_config.spi_config;

    spi_conf.mode = SpiHandle::Config::Mode::MASTER;             // we're in charge
    spi_conf.periph = SpiHandle::Config::Peripheral::SPI_2;      // Use the SPI_2 Peripheral
    spi_conf.direction = SpiHandle::Config::Direction::ONE_LINE; // TWO_LINES_TX_ONLY;

    spi_conf.datasize = 8;
    spi_conf.clock_polarity = SpiHandle::Config::ClockPolarity::LOW;
    spi_conf.clock_phase = SpiHandle::Config::ClockPhase::ONE_EDGE;
    // spi_conf.nss = SpiHandle::Config::NSS::HARD_OUTPUT;
    spi_conf.baud_prescaler = SpiHandle::Config::BaudPrescaler::PS_128;

    // Pins to use. These must be available on the selected peripheral
    spi_conf.pin_config.sclk = DaisyPatchSM::D10; // Use pin D10 as SCLK
    spi_conf.pin_config.miso = Pin();             // We won't need this
    spi_conf.pin_config.mosi = DaisyPatchSM::D9;  // Use D9 as MOSI
    spi_conf.pin_config.nss = Pin();              // DaisyPatchSM::D1;   // use D1 as NSS

    // data will flow from master to slave over just the MOSI line

    // The master will output on the NSS line
    spi_conf.nss = SpiHandle::Config::NSS::SOFT;

    display_config.driver_config.transport_config.pin_config.dc
        = DaisyPatchSM::D2;
    display_config.driver_config.transport_config.pin_config.reset
        = DaisyPatchSM::D3;
    display.Init(display_config);

    char tmp[64];

    // loop forever
    while(1)
    {
        ScopedIrqBlocker _;

        display.Fill(false);
        display.SetCursor(0, 0);
        sprintf(tmp, "%d", System::GetUs());
        display.WriteString(tmp, Font_6x8, true);
        display.Update();
    }
}

@eh2k
Copy link
Contributor

eh2k commented Dec 27, 2022

@stephenhensley,

found out the reason:

hspi_.Init.MasterKeepIOState = SPI_MASTER_KEEP_IO_STATE_DISABLE;

with SPI_MASTER_KEEP_IO_STATE_ENABLE the hardware SPI works now as expected for me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants