Are you looking at spi_dma.c?I've been looking through the SDK documentation and the example ...
By "peripheral" do you mean something connected to the SPI? So the instruction is something specific to that device, and the address is some location in the device? If so, from the perspective of the RP2040's DMA and SPI those are just data to be transmitted.For the peripheral I am using, I need to:
1. write the instruction
2. write the address
3. read x bytes (x being however many I need for what I'm trying to do)
Each DMA channel is unidirectional, but you're not restricted to a single DMA channel. You can use one in each direction to read and write simultaneously.It appears that the DMA is only for 1 direction only, for example, I can only read or I can only write using a single DMA channel at a time.
A DMA channel is going move data from one location to another, so it needs to know where to read from and write to. If you are addressing an RP2040 SPI component, its data register has a specific location in the memory map, and a specific channel will either read or write to that address, with read_increment or write_increment, respectively, set to false, since the data register is at a fixed location. On the other hand, if you are reading and writing memory, you will typically want to set the increment to true so that you can walk through a buffer....
I don't understand why there is a write and a read address...
If you a configuring a channel to read from SPI and write to a buffer in memory, you would set the read_increment to false and the write_increment to true. You can configure another channel to write from memory to SPI at the same time.
Since SPI has separate wires for transmit and receive, it always reads and writes simultaneously. So, typically, you would have two DMA channels: one to transmit and one to receive.
If you only want to read, you transmit a fill character. You can put the fill character at one address in memory and configure a channel with the read_increment to false (to repeatedly read the fill character) and the write_increment to false (to repeatedly write to the SPI component's data register). Meanwhile, another channel is configured with the read_increment to false (to repeatedly read the SPI component's data register) and the write_increment to true (to step through the addresses of a memory buffer).
If you only want to write, you ignore the received data, perhaps by setting the receive channel's memory write_increment to false so that the DMA repeatedly overwrites a single dummy variable. Meanwhile, another channel is configured to read from a memory buffer (with increment) and write to the SPI component's data register (without increment).
I don't know if helps, but I have some "real world" code (based on spi_dma.c) at https://github.com/carlk3/no-OS-FatFS-S ... /spi.c#L66.... The example provided isn't very good because it says that it's doing a loopback, not actually talking to a peripheral, which makes it more confusing, since I am not sure what is required for a loopback, and it's not doing any write address, then read, which is common for SPI devices
Have a look at section 2.5.2.2. Chaining, in RP2040 Datasheet.Also, I read that you can have one DMA start right after the other, which would be helpful for the write then read required for my peripheral. How do I achieve that?
Statistics: Posted by carlk3 — Wed Dec 27, 2023 1:13 am