DMA triggered by a GPIO

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

DMA triggered by a GPIO

1,442 Views
mikaelelharrar
Contributor III

Hi community,

It is the third ticket I open.

I dont succedded to work with gpio trigger on DMA.

I'm using Kinetis K64 + SDK 2.1.

I wrote a minimalist example, with a very simple memory to memory DMA transfer.

When I start it explicitly with EDMA_StartTransfer(&g_EDMA_Handle) so all is OK and I get the interrupt notification at the end of the transfer.

But when I configured my GPIO pin to be a trigger ( like that):

    PORT_SetPinInterruptConfig(ADS_PORT, N_DRDY_PIN, kPORT_DMAFallingEdge);
    PORT_SetPinMux(ADS_PORT, N_DRDY_PIN, kPORT_MuxAsGpio);
    GPIO_PinInit(ADC_GPIO, N_DRDY_PIN, &config);

   EnableIRQ(ADC_PORT_IRQ);

and the DMAMUX0 like:

    DMAMUX_Init(DMAMUX0);
    DMAMUX_SetSource(DMAMUX0, 0, kDmaRequestMux0PortD);
    DMAMUX_EnableChannel(DMAMUX0, 0);

    EDMA_GetDefaultConfig(&userConfig);
    EDMA_Init(DMA0, &userConfig);
    EDMA_CreateHandle(&g_EDMA_Handle, DMA0, 0);
    EDMA_SetCallback(&g_EDMA_Handle, _edma_cb, NULL);
    EDMA_PrepareTransfer(&transferConfig, srcAddr, sizeof(srcAddr[0]), destAddr, sizeof(destAddr[0]),
                             sizeof(srcAddr[0]), sizeof(srcAddr), kEDMA_MemoryToMemory);
    EDMA_SubmitTransfer(&g_EDMA_Handle, &transferConfig);

It doesnt work me at all ....

Note that I checked with scope the interrupts and this is working.

Where should be configured the trigger please.

Please help.

I don't found in the datasheet how the DMA can be hardware triggered. The only trigger the datasheet talks is in DMAMUX.

Thanks

1 Reply

872 Views
mjbcswitzerland
Specialist V

Hi

This is the code used in the uTasker project to trigger DMA transfers from port changes. This particular reference shows how to cause a second GPIO (port mirroring) to follow a port input by each change triggering a suitable DMA transfer. Complete code is available in the open source uTasker project at http://www.utasker.com/kinetis.html (search for the define DMA_PORT_MIRRORING in Port_Interrupts.h; the GPIO is configured for DMA triggering in kinetis_PORTS.h and the DMA controller set up in kinetis_DMA.h).
Apart from the limitation of the DMA channel used the code is target independent and so operates on all Kinetis parts with DMA.

INTERRUPT_SETUP interrupt_setup;                    // interrupt configuration parameters
interrupt_setup.int_type = PORT_INTERRUPT;          // identifier to configure port interrupt
interrupt_setup.int_port       = PORTB;             // the port that the interrupt input is on
interrupt_setup.int_port_bits  = PORTB_BIT16;       // UART input pin on FRDM-K64F
interrupt_setup.int_port_sense = (IRQ_BOTH_EDGES | PULLUP_ON | PORT_DMA_MODE); // DMA on both edges
interrupt_setup.int_handler = 0;                    // no interrupt handler when using DMA

// Configure the DMA trigger from the UART input pin change to toggle an alternative port so that the input signal is mirrored to that output without CPU intervention
//
static const unsigned long ulOutput = PORTC_BIT16;  // the output to be mirrored to
fnConfigDMA_buffer(9, DMAMUX0_CHCFG_SOURCE_PORTB, sizeof(ulOutput), (void *)&ulOutput, (void *)&(((GPIO_REGS *)GPIOC_ADD)->PTOR), (DMA_FIXED_ADDRESSES | DMA_LONG_WORDS), 0, 0); // use DMA channel 9 without any interrupts (free-runnning)

fnConfigureInterrupt((void *)&interrupt_setup);     // configure interrupt

Note that the DMAMUX trigger is selected as DMAMUX0_CHCFG_SOURCE_PORTB and that only one such DMA trigger is available on each of the GPIO ports (whereby ports are A, B, C, D etc.).

Regards

Mark