Currently I am using FTM timers to generate few bytes of data by toggling a pin.
But this consumes lot of CPU cycles. The signal which is generated using the FTM timer has a logic 1 for a signal which is atleast 40us held high.
I want to replace FTM using the DMA, for this I built a simple example where I try to set a port pin to high.
I am using MKV10Z64VLF7 microcontroller. The port pin I want to toggle is PTB 17.
Here is the code I used :
#include "fsl_edma.h"
#include "fsl_dmamux.h"
// Define the GPIO port and pin number to toggle
#define GPIO_PORT GPIOB
#define GPIO_PIN 17U
#define DMA_CHANNEL_NUMBER 5 // Replace 0 with the desired DMA channel number
// Define the memory buffer with the data to toggle the pin
// In this example, we use a single 32-bit word where bit 0 controls the GPIO_PIN
uint32_t edmaToggleBuffer = 0xFFFFFFFF;
// Flag to track if the DMA configuration has been done
bool dmaConfigured = false;
void configureEDMAToggle(DMA_Type *dmaBase)
{
// Initialize the DMAMUX module if required (usually done in the system initialization)
DMAMUX_Init(DMAMUX0);
// Enable the DMA channel in the DMAMUX
DMAMUX_EnableChannel(DMAMUX0, DMA_CHANNEL_NUMBER);
// Initialize the eDMA module with default configuration
edma_config_t dmaConfig;
EDMA_GetDefaultConfig(&dmaConfig);
EDMA_Init(dmaBase, &dmaConfig);
// Create an eDMA handle (if required) - Check your SDK documentation
edma_handle_t edmaHandle;
EDMA_CreateHandle(&edmaHandle, dmaBase, DMA_CHANNEL_NUMBER);
// Set up the eDMA transfer
edma_transfer_config_t transferConfig;
EDMA_PrepareTransfer(&transferConfig, &edmaToggleBuffer, sizeof(uint32_t),
(void *)(&(GPIO_PORT->PDOR)), sizeof(uint32_t),
sizeof(uint32_t), sizeof(uint32_t), kEDMA_MemoryToPeripheral);
// Submit the transfer configuration to the eDMA channel (if required) - Check your SDK documentation
EDMA_SubmitTransfer(&edmaHandle, &transferConfig);
// Enable the eDMA channel request (if required) - Check your SDK documentation
EDMA_StartTransfer(&edmaHandle);
// Set the flag to indicate that the DMA has been configured
dmaConfigured = true;
}
void main (void)
{
// Check if DMA configuration is done
if (dmaConfigured == false) {
// Toggle the GPIO pin using DMA for the first time only
configureEDMAToggle(DMA0);
}
}
Hi @Mitun92
I would like to know more details of your application.
I understand that you are trying to use DMA to write into the GPIO->PDOR register to toggle the pin, is my understanding correct?
Please share more information of you application to look for an alternative, DMA is not mainly used for this.
Best Regards, Miguel.
Yes, I would like to use DMA to write into the GPIO->PDOR register to toggle the pin.
My application is to send few data bytes at a fixed interval of every 50ms. The 50ms timeslot is controlled by my Time Slot Monitoring State machine. But to generate the data I used a FTM timer, whích created a event everytime the counter had a overflow, with this I could Hold or Free a Port signal to generate data. The problem of using this method of using FTM timer was that the FTM interruput for the overflow event, interferes with my CPU run time. Thats why I am looking for alternatives.
I am attaching a illustration on how my data bytes would look like :
Hi @Mitun92
Thanks for the information, teorically it should be possible to toggle the pin with the dma, however, i don't know if you will be able to replicate the timing on the toggle such as the timer.
I recommend you to test this on a different project to verify the correct configuration and the toggle of the pin:
Let me know if I can help you with something else.
Best Regards.