You're not using DMASPI as intended. Some details of your code are "backwards" or circumvent the concepts behind DMASPI.
First of all, I'll try to answer the questions from your previous posts:
Currently transferring using dmaspi with a while(trx.busy())){} afterward takes longer on my OLED screen write tests than SPI.transactions.
2000micros vs 760micros
any ideas why?
I don't know how large the buffer for that test was, but if it was large enough for DMASPI to have any effect that compensates for the additional overhead, chances are that you didn't give DMASPI the right SPI settings through a ChipSelect object. These set up the SPI for the actual transaction, using classic SPI transaction methods. DMASPI builds a "transfer" on top of that. if there's no ChipSelect object to use, DMASPI will use default settings which might simply be slower than what you use in your code. Without seeing all your test code, it's hard to tell what's going on.
is it possibly taking time waiting on potential input from the SPI? If so, is there a way to only send and not worry about any receiving?
alternately, could this have anything to do with the 8bit transfers vs 32 bit DMA hardware?
If you don't pass a return buffer to your transfer object, any incoming data is discarded. This is exactly what you do in your last post, so you're good to go in that respect. SPI can, by its very basic nature, not "wait" for incoming data, it will just clock in what's present on the DIN pin.
The DMA engine can handle 8-bit transfers just fine, this has been demonstrated before and it also works for DMASPI.
No let's get to the code snippet in your last post. I'll start with some concepts behind DMASPI.
- When a Transfer is registered with the DMASPI engine, it is appended to a queue of pending transfers.
- When the DMASPI engine is not "stopped" (see below), it will start a pending transfer after it has been registered (if the queue was empty before) or when the previous transfer has finished
- A transfer object can be equipped with a ChipSelect object. The ChipSelect object is responsible for selecting a slave and setting up the right SPI settings. Some basic ChipSelect classes are included with DMASPI and the most common one, "ActiveLowChipSelect", is demonstrated in the example code. Apply correct SPISettings there.
- While a transfer is being processed, its source and destination buffers must remain in scope. Otherwise, wrong data might be sent to the slave, or (probably worse) existing data in the master's RAM might be overwritten.
- The DMASPI engine can be stopped and restarted to have classic, blocking SPI operations between DMA transfers. You need this to properly send commands to your display. However, when stop() is called, this will just set a stop request flag and the engine will finish any transfer that is currently in progress, but it will not start any new pending transfer. This is also demonstrated in the example.
Your code starts by waiting for the current transfer to finish. This will probably waste CPU time. Simply add a method that checks for trx.busy() == false to your display class and start drawing only if that is the case. If the transfer is not busy, it's safe to send the next frame. Try to think in states, not in procedures, when writing asynchronous code. You can only get less wasted CPU time if you don't wait for the transfer to finish. Instead, check if it is finished and do something useful until it is. Check every 20 ms for a maximum of 50 fps. A fast CPU with little to draw can easily do 100 fps or more if not throttled, and the display will look like garbage while it's simply trying to keep up with your data.
On top of that, you use the SPI for sending commands to the display immediately after you found out that the transfer is not busy any more. This is probably ok for applications where there is only one module that uses the SPI, but in more complex situations the DMASPI engine might already be using the SPI for its next pending transfer. So you need to pause the DMASPI engine using stop(), and wait until it has actually stopped!
Move your chip select handling to a chip select object. This will make sure that the chip select line is only asserted just before the transfer actually starts, and that it is only deasserted when the transfer has finished. Your code, as it is now, deasserts CS immediately after registering the transfer, and - depending on the SPI speed - no or just one byte has been shifted out by that time. The rest of the data will go nowhere because the slave is not expecting any further data!
I'll not write a complete solution for your problem now because I think that others can benefit more from these explanations than from a specific solution to a specific problem. I'm well aware that SPI with DMA is a complex matter, and the library is not less complex. However, it provides a lot of the tools necessary to get going even in complex environments. I hope that this will get you a few steps further. When you provide an attempt at implementing the above hints, I'm happy to help further.