azhel12/Zhele

SPI class doesn't work.

Opened this issue · 16 comments

SPI Functions (SendAsync, WriteAsync, WriteAsyncNoIncrement, ReadAsync) associated with dma do not work and freeze.

Thank you for report, does at least one byte (one chunk) of data transmitted/received? I have been remove all interrupt handlers include DMA from library for optimize binary code (no handler -> no template instance). So, you should add

void DMAx_IrqHandler() {
    DmaX::IRQHandler();
};

Good afternoon.
I'm using VisualGDB and Microsoft Visual Studio.

Yes, I have added an interrupt handler. As for the byte transfer, I'll come home tonight and check it out. In the old version it worked without problems.

max7219.zip

The problem was with the optimization level -Os did not work -O1 worked. It worked strangely before.

Ok, ty for project archive, I'll build it and fix the bug!

I have tried build and run code in Proteus, it works. At least SPI commands are equal for code with/without DMA, for code with/without Os optmization.

Also I ordered max7219 module and repeat experiment later (on this weekends).

I reproduced problem. It's really no info on display with O1, Os, Og options.

I think that it is 2 reasons:

  1. For optimized build program work significantly faster.
  2. SPI Spi::Busy() method depend on BSY flag which should be cleared. It may occured when TXempty, not transmit complete!!!
  3. I tried replace waiting Spi::Busy() with waiting Dma::Transfer Complete(), but got same result. Its similar reason.

So, I fixed your code by insert small delay (1ms works) after SPI transfer:

  DevSPI::WriteAsync(spi data, maxbytes);
  while (DevSPI::Busy()) {};		
  delay_ms<1>(); // Delay

It's very very bad solution and I'll think about this case (it may be actual for i2c, uart, etc).

Sorry for this bug:(

UPD: other solution: fill whole display (allocate 2N bytes, fill it every second and send all in one transfer)

Thank you. And this is also with the library for ili9341. I did something like this.

Cool! You can do pull request or allow me add your code (with you as author of course).

Ok, no problem, I will make some improvements to the ili9341, ili9488 libraries.

Good morning!
For verification, I inserted functions into '\include\zhele\common\spi.h':
`static bool ReadyDmaTx()
{
return !_DmaTx::Ready();
}

static bool ReadyDmaRx()
{
return !_DmaRx::Ready();
}`

Now it works like this:

Spi1::WriteAsyncNoIncrement(linebuff, len * 3, nullptr); while (Spi1::ReadyDmaTx()) ; while (Spi1::Busy());

Hello, good! In fact, it's not best practice to wait async (DMA) operation synchronously, but in this case its OK solution.

I recommend to add two writeX methods in your drivers: Write and WriteAsync to allow user choose.

ILI9488 I Will Make The Video a Little Later.

Uploading drivers.zip…

It's link on this issue:)