FRDM-K64F DMA restart from GPIO interrupt

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

FRDM-K64F DMA restart from GPIO interrupt

1,343 Views
Rashmitha_Nair
Contributor III

Hi,

Is there a way to mention a GPIO interrupt as a source for restarting DMA transfer from first location?

I understand DMA MUX settings can be defined for specifying certain ports as below, but I use PORT B Pin19 for a button press too and I would like to use an 18khz clock signal received on PORT B Pin2 to restart DMA transfer.

Rashmitha_Nair_0-1655900519667.png

 

 

Regards,

Rashmitha

0 Kudos
7 Replies

1,314 Views
Julián_AragónM
NXP TechSupport
NXP TechSupport

Hello @Rashmitha_Nair

The DMAMUX table you are showing is correct, you can assign an entire port to the DMA request source, which will activate the restart from any input from the desired port, so as an alternative you could reposition your first button reset, or utilize a different port.

Best regards,

Julian

0 Kudos

1,306 Views
Rashmitha_Nair
Contributor III

Hi @Julián_AragónM,

Thank you for your reply.

Is there a DMA count register that I can reset in a GPIO ISR for it to start from the first sample again?

My current DMA initialization is as below

 

  /**********************************************************************************
   * Channel n DMA Setup
   * ********************************************************************************
   */

    // eDMA TCD Signed Source Address Offset (DMA_TCD1_SOFF) i.e. source address increment per DMA minor loop
    *(signed short *)(eDMA_DESCRIPTORS + 0x024) = sizeof(unsigned short);

    // eDMA TCD Signed Destination Address Offset (DMA_TCD1_DOFF) i.e. destination address is not incremented
    *(signed short *)(eDMA_DESCRIPTORS + 0x034) = 0;

    // eDMA TCD Last Destination Address Adjustment/Scatter Gather Address (DMA_TCD1_DLASTSGA). No destination displacement on transmit buffer completion
    *(volatile signed long *)(eDMA_DESCRIPTORS + 0x038) = 0;

    // eDMA TCD Last Source Address Adjustment (DMA_TCD1_SLAST). When the buffer has been transmitted set the destination back to the start of the buffer.
    *(volatile unsigned long *)(eDMA_DESCRIPTORS + 0x02c) = (-(signed long)(ulBufferLength));
    //*(volatile unsigned long *)(eDMA_DESCRIPTORS + 0x02c) = (-(signed long)(sizeof(PWMAData)));

    // eDMA TCD Transfer Attributes (DMA_TCD1_ATTR). Transfer size is half-words i.e. 16 bits, the same as the destination register width.
    *(unsigned short *)(eDMA_DESCRIPTORS + 0x026) = (0x0001 | 0x0100);

    // eDMA TCD Source Address (DMA_TCD1_SADDR).
    *(volatile unsigned long *)(eDMA_DESCRIPTORS + 0x020) = (unsigned long)ptrPWMABuffer;

    // eDMA TCD Control and Status (DMA_TCD1_CSR). Free-running mode without any interrupt
    *(volatile unsigned short *)(eDMA_DESCRIPTORS + 0x03c) = 0;

    // eDMA TCD Destination Address (DMA_TCD1_DADDR). Destination address is the FTM CnV register (the PWM register)
    *(volatile unsigned long *)(eDMA_DESCRIPTORS + 0x030) = (unsigned long)((FTM0_BASE_ADDR + FTM0_C6V_OFFSET));

    // eDMA TCD Minor Byte Count (Minor Loop Mapping Disabled) (DMA_TCD1_NBYTES_MLNO). Each request starts a single transfer of this size (minor byte transfer count)
    *(volatile unsigned long *)(eDMA_DESCRIPTORS + 0x028) = sizeof(unsigned short);

    // eDMA TCD Beginning Minor Loop Link, Major Loop Count (Channel Linking Disabled) (DMA_TCD1_BITER_ELINKNO).
    // The number of service requests to be performed each buffer cycle.
    *(unsigned short *)(eDMA_DESCRIPTORS + 0x03e) = *(volatile signed short *)(eDMA_DESCRIPTORS + 0x036) = (signed short)(ulBufferLength / sizeof(unsigned short));
    //*(unsigned short *)(eDMA_DESCRIPTORS + 0x03e) = *(volatile signed short *)(eDMA_DESCRIPTORS + 0x036) = (signed short)(sizeof(PWMAData) / sizeof(unsigned short));


  /**********************************************************************************
   * Channel n+1 DMA Setup
   * ********************************************************************************
   */

    // eDMA TCD Signed Source Address Offset (DMA_TCD2_SOFF) i.e. source address increment per DMA minor loop
    *(signed short *)(eDMA_DESCRIPTORS + 0x044) = sizeof(unsigned short);

    // eDMA TCD Signed Destination Address Offset (DMA_TCD2_DOFF) i.e. destination address is not incremented
    *(signed short *)(eDMA_DESCRIPTORS + 0x054) = 0;

    // eDMA TCD Last Destination Address Adjustment/Scatter Gather Address (DMA_TCD2_DLASTSGA). No destination displacement on transmit buffer completion
    *(volatile signed long *)(eDMA_DESCRIPTORS + 0x058) = 0;

    // eDMA TCD Last Source Address Adjustment (DMA_TCD2_SLAST). When the buffer has been transmitted set the destination back to the start of the buffer.
    *(volatile unsigned long *)(eDMA_DESCRIPTORS + 0x04c) = (-(signed long)(ulBufferLength));
    //*(volatile unsigned long *)(eDMA_DESCRIPTORS + 0x04c) = (-(signed long)(sizeof(PWMBData)));

    // eDMA TCD Transfer Attributes (DMA_TCD2_ATTR). Transfer size is half-words i.e. 16 bits, the same as the destination register width.
    *(unsigned short *)(eDMA_DESCRIPTORS + 0x046) = (0x0001 | 0x0100);

    // eDMA TCD Source Address (DMA_TCD2_SADDR).
    *(volatile unsigned long *)(eDMA_DESCRIPTORS + 0x040) = (unsigned long)ptrPWMBBuffer;

    // eDMA TCD Control and Status (DMA_TCD2_CSR). Free-running mode without any interrupt
    *(volatile unsigned short *)(eDMA_DESCRIPTORS + 0x05c) = 0;

    // eDMA TCD Destination Address (DMA_TCD2_DADDR). Destination address is the FTM CnV register (the PWM register)
    *(volatile unsigned long *)(eDMA_DESCRIPTORS + 0x050) = (unsigned long)((FTM0_BASE_ADDR + FTM0_C7V_OFFSET));

    // eDMA TCD Minor Byte Count (Minor Loop Mapping Disabled) (DMA_TCD2_NBYTES_MLNO). Each request starts a single transfer of this size (minor byte transfer count)
    *(volatile unsigned long *)(eDMA_DESCRIPTORS + 0x048) = sizeof(unsigned short);

    // eDMA TCD Beginning Minor Loop Link, Major Loop Count (Channel Linking Disabled) (DMA_TCD2_BITER_ELINKNO).
    // The number of service requests to be performed each buffer cycle.
    *(unsigned short *)(eDMA_DESCRIPTORS + 0x05e) = *(volatile signed short *)(eDMA_DESCRIPTORS + 0x056) = (signed short)(ulBufferLength / sizeof(unsigned short));
    //*(unsigned short *)(eDMA_DESCRIPTORS + 0x05e) = *(volatile signed short *)(eDMA_DESCRIPTORS + 0x056) = (signed short)(sizeof(PWMBData) / sizeof(unsigned short));


  /**********************************************************************************
   * Sync Channel DMA Setup
   * ********************************************************************************
   */

    // eDMA TCD Signed Source Address Offset (DMA_TCD3_SOFF) i.e. source address increment per DMA minor loop
    *(signed short *)(eDMA_DESCRIPTORS + 0x064) = sizeof(uint8_t);

    // eDMA TCD Signed Destination Address Offset (DMA_TCD3_DOFF) i.e. destination address is not incremented
    *(signed short *)(eDMA_DESCRIPTORS + 0x074) = 0;

    // eDMA TCD Last Destination Address Adjustment/Scatter Gather Address (DMA_TCD3_DLASTSGA). No destination displacement on transmit buffer completion
    *(volatile signed long *)(eDMA_DESCRIPTORS + 0x078) = 0;

    // eDMA TCD Last Source Address Adjustment (DMA_TCD3_SLAST). When the buffer has been transmitted set the destination back to the start of the buffer.
    *(volatile unsigned long *)(eDMA_DESCRIPTORS + 0x06c) = (-(signed long)(syncBufferLength));
    //*(volatile unsigned long *)(eDMA_DESCRIPTORS + 0x06c) = (-(signed long)(sizeof(SyncData)));

    // eDMA TCD Transfer Attributes (DMA_TCD3_ATTR). Transfer size is bytes i.e. 8 bits, the same as the destination register width.
    *(unsigned short *)(eDMA_DESCRIPTORS + 0x066) = 0x000;

    // eDMA TCD Source Address (DMA_TCD3_SADDR).
    *(volatile unsigned long *)(eDMA_DESCRIPTORS + 0x060) = (unsigned long)ptrSYNCBuffer;

    // eDMA TCD Control and Status (DMA_TCD3_CSR). Free-running mode without any interrupt
    *(volatile unsigned short *)(eDMA_DESCRIPTORS + 0x07c) = 0;

    // eDMA TCD Destination Address (DMA_TCD3_DADDR). Destination address is the FTM CnV register (the PWM register)
    *(volatile unsigned long *)(eDMA_DESCRIPTORS + 0x070) = (unsigned long)((FTM0_BASE_ADDR + 0x58));

    // eDMA TCD Minor Byte Count (Minor Loop Mapping Disabled) (DMA_TCD3_NBYTES_MLNO). Each request starts a single transfer of this size (minor byte transfer count)
    *(volatile unsigned long *)(eDMA_DESCRIPTORS + 0x068) = sizeof(uint8_t);

    // eDMA TCD Beginning Minor Loop Link, Major Loop Count (Channel Linking Disabled) (DMA_TCD3_BITER_ELINKNO).
    // The number of service requests to be performed each buffer cycle.
    *(unsigned short *)(eDMA_DESCRIPTORS + 0x07e) = *(volatile signed short *)(eDMA_DESCRIPTORS + 0x076) = (signed short)(syncBufferLength / sizeof(uint8_t));
    //*(unsigned short *)(eDMA_DESCRIPTORS + 0x07e) = *(volatile signed short *)(eDMA_DESCRIPTORS + 0x076) = (signed short)(sizeof(SyncData) / sizeof(unsigned short));


  /**********************************************************************************
   * Channel n DMA Multiplexer Setup
   * ********************************************************************************
   */

    // System Clock Gating Control Register 6 (SIM_SCGC6). Enable DMA Multiplexer.
     *(volatile unsigned long *)(SIM_BLOCK + 0x103c) |= 0x00000002;

    // Channel Configuration register (DMAMUX_CHCFG1). Connect trigger source to DMA channel 1.
     *(unsigned char *)(DMAMUX0_BLOCK + 0x01) = (unsigned char)(DMAMUX_SOURCE_SLOT_FTM0_CH6 | 0x80);


  /**********************************************************************************
   * Channel n+1 DMA Multiplexer Setup
   * ********************************************************************************
   */

    // Channel Configuration register (DMAMUX_CHCFG2). Connect trigger source to DMA channel 2.
     *(unsigned char *)(DMAMUX0_BLOCK + 0x02) = (unsigned char)(DMAMUX_SOURCE_SLOT_FTM0_CH7 | 0x80);


   /**********************************************************************************
    * Sync Channel DMA Multiplexer Setup
    * ********************************************************************************
    */

     // Channel Configuration register (DMAMUX_CHCFG2). Connect trigger source to DMA channel 3.
     *(unsigned char *)(DMAMUX0_BLOCK + 0x03) = (unsigned char)(DMAMUX_SOURCE_SLOT_FTM0_CH6 | 0x80);



  /**********************************************************************************
   * Enable DMA Channels
   * ********************************************************************************
   */

    // eDMA Enable Request Register (DMA_ERQ). Enable the DMA channel 1 operation for FTM channel n
     *(volatile unsigned long *)(eDMA_BASE_ADDR + 0x00c) |= 0x00000002;

    // eDMA Enable Request Register (DMA_ERQ). Enable the DMA channel 2 operation for FTM channel n + 1
     *(volatile unsigned long *)(eDMA_BASE_ADDR + 0x00c) |= 0x00000004;

     // eDMA Enable Request Register (DMA_ERQ). Enable the DMA channel 3 operation for FTM channel Sync
     *(volatile unsigned long *)(eDMA_BASE_ADDR + 0x00c) |= 0x00000008;

 

Regards,

Rashmitha

0 Kudos

1,288 Views
Julián_AragónM
NXP TechSupport
NXP TechSupport

Hi @Rashmitha_Nair,

I'm sorry for the misunderstanding, could you please provide more details about what you're trying to achieve? With "from the first sample again?" do you mean the start of transmission of the DMA, or any of the FIFO arrays? Or do you have linked any other peripheral with the DMA request?

Best regards, Julian

0 Kudos

1,282 Views
Rashmitha_Nair
Contributor III

Hi @Julián_AragónM ,

Yes, I am linking the FTM with DMA to generate SPWM based on samples stored in an array. The DMA source address is the array and destination is FTM0 CnV register for CH6 and CH7 .

I would like to restart the whole DMA transmission when I receive an interrupt on PTB2 pin.

I am already resetting the FTM counter and restarting the FTM clock in the PTB2 ISR, but for the DMA resetting; when I just re-write the source start address in the GPIO ISR it triggers a fault and I end up in a default fault ISR.

Could you please help me with the list of DMA registers (along with the order in which they need to be written) that are needed for a DMA restart?

 

Regards,

Rashmitha

0 Kudos

1,263 Views
Julián_AragónM
NXP TechSupport
NXP TechSupport

Hi @Rashmitha_Nair,

Here is a community post with a similar problem, and the attached file will prove useful for the hardware trigger you are trying to achieve.

Solved: Need Help of K60 DMA with GPIO - NXP Community

Best regards, Julian

0 Kudos

1,253 Views
Rashmitha_Nair
Contributor III

Hi @Julián_AragónM ,

The post you shared is trying to use PORT E as an interrupt source for DMA,

but in my case since FTM module is already linked as the source. Therefore, I would like to manually use a GPIO ISR to restart the DMA.

Could you please help me with the list of registers that are essential for such a restart?

 

Regards,

Rashmitha

0 Kudos

1,174 Views
Julián_AragónM
NXP TechSupport
NXP TechSupport

Hi @Rashmitha_Nair,

If you want to manually set-up a GPIO as an interrupt to restart a transfer, you will have to implement the code yourself, as we do not have any examples or SDKs in this specific scenario. The key register will be DMA_TCDn_CSR (START) as if this is active, the channel is requesting service. Other than that, you could look into the project I've already shared with you for support, and the frdmk64f_edma_channel_link example to look into the interruptions needed.

Best regards, Julian 

0 Kudos