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
Feature request: Add support for SPI (optionally PIO) with DMA Transfers #1192
Comments
@earlephilhower If you want to test it, you can use the PicoADK board I've sent you some time ago. |
This is pretty low prio for me, to be honest. If it's important for you, I think it's doable without too many tears. The |
@earlephilhower For the PicoADK it would be pretty important. I've tried my luck without success so far. volatile const uint16_t txbuf[TEST_SIZE] __attribute__((aligned(TEST_SIZE * sizeof(uint16_t)))) = {
0 << 11,
1 << 11,
2 << 11,
3 << 11,
4 << 11,
5 << 11,
6 << 11,
7 << 11
}; |
Spitballing here, but I think you'd set up an ABM INPUT stream from the SPI read FIFO, and then externally set up a recurrent DMA loop off a timer of In this case I'd probably make a special-purpose SPI setup since this looks to have rather different requirements than the general purpose one... |
If you would find some time for this, I would be very grateful! I am not sure I understood your last message. |
+1 for non-blocking SPI communication! This gets more important as the peripheral's max tx rate gets more slow. My current project spends over 20% of its main loop blocked on an SPI transfer of < 20 bytes. The transfer speed itself wouldn't be a problem if I could do something else with those cycles. |
I tried hacking out some code for this today and ran into a roadblock. While getting DMA set up to feed/eat the SPI data is straightforward enough, actually knowing when the SPI transaction is completed is not doable via IRQ. There is no IRQ for SPI done, there is no IRQ even for SPI FIFO empty. So, while it would be possible to make a
Given that, I'm not sure it's so useful. Thoughts? |
You know way more about this than I do :D, but: Would DMA SPI be applicable to reading (part of) a file from SD card?
As long as steps 2-4 always take longer than the SPI transfer, a "SPI done" interrupt would be useless in this case. |
Yeah, but not a precise half-empty one. Given the "or fewer" part I'm not sure what the designer expected the code to do.
Actually, that seems like a possibility. No clock stretching allowed like in I2C so you can know timing. I'd need to think about the granularity of alarms, though. Might normally be too small or something...
The SPI is also used to read things like FAT tables and directory entries inside the SDFat code so w/o massive rewriting internally I don't think it could work. Your data reads are a very special case, I think. Inside SDFat there is no differentiation between what purpose the SPI access is being performed. |
Couldn't the SPI transaction / reading be done using the DREQ from the timer? I've seen some examples where SPI transfers were done at 44100Hz rate, but can't find it anymore. |
It's not quite that simple when talking to SD cards. Even if you didn't have a filesystem and used it like a tape you'd still need to initiate each chunk of sector reads and wait for ready. So you'd need to buffer anyway, and in that case you'd probably just want to run as fast as possible and not limit its speed. Add a filesystem on top and you could end up needing to read a different address every 512 bytes (plus maybe peeking at the FAT if you don't cache it because it's too big). |
Ah, I see. For an SPI ADC / DAC that would probably make sense, though. |
Fixes #1192 Uses DMA operations to avoid the need to bit-bang or busy wait for SPI operations that might be very slow. Optional, adds new API calls to enable. Simple example included.
Fixes #1192 Uses DMA operations to avoid the need to bit-bang or busy wait for SPI operations that might be very slow. Optional, adds new API calls to enable. Simple example included.
For some applications like controlling a SPI display, DAC or ADC DMA would make sense to save some CPU cycles.
An example is my PicoADK Board, which has an on-board SPI ADC128S102 8ch 1msps ADC.
With DMA, the SPI ADC could be free-running or sampled at a certain interval without involving the CPU.
If this would be done using the HW SPI peripheral, the CS pin would be most likely limited to the CS pins listed
for the corresponding CS options in the pin matrix.
An alternative approach would be to use PIO (there is a reference implementation for SPI). This would still allow
for high clock rates, but more flexibility to the choice of the SPI pins.
The text was updated successfully, but these errors were encountered: