DMA, memory to memory, memory to peripheral. (NXP, Kinetis, i.MX RT1020) - Page 1
Forum section: electronics / general

author: luiHS
author_rank: Frequent Contributor
timestamp: October 15, 2019, 03:11:15 am
content: Hi.I have some doubts about the handling of the DMA, I need to configure the DMA to send and receive data from/to the GPIO ports, using microcontrollers Kinetis and RT1020 of NXP. The SDK examples are only for peripherals such as SPI, UART, I2C, I2S and for memory to memory, but there are none to receive/send data from/to GPIO ports.In addition to preparing the transfer, I see that three configurations can be used, memory-memory, peripheral-memory and memory-peripheral.EDMA_PrepareTransfer(&transferConfig, srcAddr, sizeof(srcAddr), destAddr, sizeof(destAddr),sizeof(srcAddr), sizeof(srcAddr), kEDMA_MemoryToMemory);typedef enum _edma_transfer_type{kEDMA_MemoryToMemory = 0x0U, / *! <Transfer from memory to memory * /kEDMA_PeripheralToMemory, / *! <Transfer from peripheral to memory * /kEDMA_MemoryToPeripheral, / *! <Transfer from memory to peripheral * /} edma_transfer_type_t;The question is whether I could use the DMA SDK examples for memory-to-memory transfers, replacing the source or destination address, with the GPIO port address, so that I can send or receive data, using DMA, from/to GPIO ports. . Although I still don't know how useful the parameter is that in the preparation it indicates the type of transfer.

author: nctnico
author_rank: Super Contributor
timestamp: October 15, 2019, 09:12:50 am
content: I'll admit I don't have much experience with DMA since I don't use it that often. But let me take a stab it it: The first step is to study the internal busses to see if the DMA controller has access to the peripheral you want to use. In case of GPIO you'll also need some kind of trigger to start the transfer so likely you need a way to use the match output of a timer to the DMA controller in order to do the transfers at regular intervals. The DMA method (memory to peripheral for example) controls if the address of the DMA controller is increment for each transfer or not. Typically you'll want to have a fixed address at the peripheral side and an incrementing address at the memory side.

author: donotdespisethesnake
author_rank: Super Contributor
timestamp: October 15, 2019, 09:18:54 pm
content: Wouldn't you just use a memory to memory transfer?A GPIO doesn't have a receive/transmit ready signal, so there is nothing to trigger a DMA.

author: errorprone
author_rank: Contributor
timestamp: October 15, 2019, 09:49:46 pm
content: From what I remember of the SDK the different modes are used to setup the auto increment for source and destination addresses. So memory to memory will increment both while peripheral to memory will only increment the destination address.

author: luiHS
author_rank: Frequent Contributor
timestamp: October 16, 2019, 12:34:53 am
content: Quote from: errorprone on October 15, 2019, 09:49:46 pmYes, that seems after looking at the sources of the transfer preparation function, apply a different offet to source or destiny address according to type of transfer.Then I understand that I could use the SDK example using memory to memory DMA, changing the destination or source address to the address of the first GPIO port, configuring the number of ports as 8 (1 byte) blocks and selecting the type of transfer, memory to peripheral or peripheral to memory.case kEDMA_MemoryToMemory:config->destOffset = (int16_t)destWidth;config->srcOffset = (int16_t)srcWidth;break;case kEDMA_MemoryToPeripheral:config->destOffset = 0;config->srcOffset = (int16_t)srcWidth;break;case kEDMA_PeripheralToMemory:config->destOffset = (int16_t)destWidth;config->srcOffset = 0;break;typedef struct _edma_transfer_config{uint32_t srcAddr; /*!< Source data address. */uint32_t destAddr; /*!< Destination data address. */edma_transfer_size_t srcTransferSize; /*!< Source data transfer size. */edma_transfer_size_t destTransferSize; /*!< Destination data transfer size. */int16_t srcOffset; /*!< Sign-extended offset applied to the current source address to form the next-state value as each source read is completed. */int16_t destOffset; /*!< Sign-extended offset applied to the current destination address to form the next-state value as each destination write is completed. */uint32_t minorLoopBytes; /*!< Bytes to transfer in a minor loop*/uint32_t majorLoopCounts; /*!< Major loop iteration count. */} edma_transfer_config_t;

author: luiHS
author_rank: Frequent Contributor
timestamp: October 16, 2019, 12:46:31 am
content: Quote from: donotdespisethesnake on October 15, 2019, 09:18:54 pmThere is an external clock signal to trigger the DMA. Six data signals and one clock signal.

author: donotdespisethesnake
author_rank: Super Contributor
timestamp: October 16, 2019, 07:16:51 am
content: Quote from: luiHS on October 16, 2019, 12:46:31 amThat's right. For GPIO you need to use the periodic trigger function.