SPI DMA tx not working with seed

Now I trying transmit SPI to use Neopixel with seed.
This attempt succeeded with BlockingTransmit() but not with DmaTransmit().
When checking with an oscilloscope, it appears that in the case of DmaTransmit(), the data in the buffer is sent only once, but is not sent after the second time.
I created minimal code that reproduces the issue by modifying SpiDmaTransmit.cpp from the official example.
There are comments in the modified section.
How should I fix this?

#include "daisy_seed.h"//I using seed not patch
#include "daisysp.h"

using namespace daisy;
using namespace daisysp;

DaisySeed hw;//I using seed not patch

uint8_t DMA_BUFFER_MEM_SECTION buffer[4] = {0, 1, 2, 3};

int main(void)
{
	hw.Init();
	SpiHandle spi_handle;
	SpiHandle::Config spi_conf;
	spi_conf.mode = SpiHandle::Config::Mode::MASTER;
	spi_conf.periph = SpiHandle::Config::Peripheral::SPI_1; // Use the SPI_1 Peripheral

	spi_conf.pin_config.sclk = Pin();//not used because I use this spi for neopixel
	spi_conf.pin_config.miso = Pin(); 
	spi_conf.pin_config.mosi = Pin(PORTB, 5); //data out I need only this
	spi_conf.pin_config.nss = Pin(); 

	spi_conf.direction = SpiHandle::Config::Direction::TWO_LINES_TX_ONLY;
	spi_conf.nss = SpiHandle::Config::NSS::HARD_OUTPUT;
	spi_handle.Init(spi_conf);

	while(1) 
	{
		//spi_handle.BlockingTransmit(buffer, 4, 100); //this is working
		spi_handle.DmaTransmit(buffer, 4, NULL, NULL, NULL); //this is not working

		System::Delay(500);
	}
}

:cry:‎‎‎‎‎

Hi :slight_smile:

I’m looking into SPI myself right and found your post. I cannot tell you what’s wrong, but did you confirm the exact same config works with a blocking transfer? Also, do you have a debug probe, and can check if the code gets stuck somewhere?

Can the clock pin actually be set to Pin() ? I don’t know how NeoPixels work, or SPI without a clock in general, but it seems like something to check, in case you didn’t.

Sorry if this doesn’t help.

Thank you for your cooperation.
Actually, I asked a friend to look into this issue, and it’s been resolved now.
I was going to report it here as well, but I kept putting it off.
As pointed out, it seems the clk pin must be specified.

At this point DMA worked, but the output data was glitching in the test code. It seems initializing the DMA buffer when I declare it doesn’t work, causing the data to glitch. This also puzzled me, so I’m writing this up in case it helps someone.

Ah, good to hear. So you have to assign values to the buffer again, after declaration?

Yes, I had to initialize DMA buffer separately from the declaration.
Like this:

#include <algorithm>
#include <array>

#include "daisy_seed.h"
#include "daisysp.h"

using namespace daisy;
using namespace daisysp;

static DaisySeed hw;

int main(void)
{
hw.Init();
SpiHandle spi_handle;
SpiHandle::Config spi_conf;
spi_conf.mode = SpiHandle::Config::Mode::MASTER;
spi_conf.periph = SpiHandle::Config::Peripheral::SPI_1;

spi_conf.pin_config.sclk = Pin(PORTG, 11);
spi_conf.pin_config.miso = Pin();
spi_conf.pin_config.mosi = Pin(PORTB, 5);
spi_conf.pin_config.nss = Pin();

spi_conf.direction = SpiHandle::Config::Direction::TWO_LINES_TX_ONLY;
spi_conf.nss = SpiHandle::Config::NSS::SOFT;
spi_handle.Init(spi_conf);

constexpr auto buffer_size = 10;
static std::array<uint8_t, buffer_size> DMA_BUFFER_MEM_SECTION buffer;
std::fill(buffer.begin(), buffer.end(), 1);

while(1){
    spi_handle.DmaTransmit(buffer.data(), buffer_size, NULL, NULL, NULL);
    System::Delay(1);
    }
}

Oh, interesting! Thanks for the details