PSoC 4 DMA Interrupt?

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
lock attach
Attachments are accessible only for community members.
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

I've been studying the usage of DMA.

And today, I'm stuck with DMA interrupt (or callback).

What I would like to do is set an ISR or callback to be called after transfer completion.

Although I think I set up my_dma_isr to be called at the transfer completion, it's never called.

I wonder if there is/are more to be done to make this work.

I would appreciate it if someone can teach me how to correctly set up this.

    DMA_Start((void*)source, destination) ;

    DMA_SetInterruptCallback(my_dma_isr) ;

I've been trying with CY8CKIT-044.

schematic

001-schematic.JPG

pins

002-pins.JPG

DMA Config

003-DMA_Config_1.JPG

004-DMA_Config_2.JPG

Tera Term log

Note: DMA transfer seems to be done OK, except the callback is not being called.

005-TeraTerm-log.JPG

Oscilloscope waveform

Red: int_out signal, which is supposed to be the interrupt monitoring signal

Yellow: TRO (Tr_out) signal

IMG_4516.JPG

main.c

===================

#include "project.h"

#include "stdio.h"

#define STR_BUF_LEN 54

char str[STR_BUF_LEN+1] ;

void print(char *str)

{

    UART_UartPutString(str) ;

}

void cls(void)

{

    print("\x1b[2J\x1b[;H") ;

    CyDelay(1) ;

}

void splash(void)

{

    cls() ;

    snprintf(str, STR_BUF_LEN, "DMA Test (%s %s)\n\r", __DATE__, __TIME__) ;

    print(str) ;

}

volatile uint8_t source[32] = { 0u } ;

uint8_t destination[32] ;

CY_ISR(my_dma_isr)

{

    int_out_Write(1) ;

}

void dump_memory(void)

{

    int i ;

    print("Src: ") ;

    for (i = 0 ; i < 10 ; i++ ) {

        snprintf(str, STR_BUF_LEN, "%02X ", source) ;

        print(str) ;

    }

    print("\n\r") ;

    print("Dst: ") ;

    for (i = 0 ; i < 10 ; i++ ) {

        snprintf(str, STR_BUF_LEN, "%02X ", destination) ;

        print(str) ;

    }

    print("\n\r\n\r") ;

    CyDelay(10) ;

}

void prepare_source(int offset)

{

    int i ;

    for (i = 0 ; i < 8 ; i++ ) {

        source = i + offset ;

    }

}

int main(void)

{

    int i = 0 ;

   

    CyGlobalIntEnable; /* Enable global interrupts. */

    DMA_Start((void*)source, destination) ;

    DMA_SetInterruptCallback(my_dma_isr) ;

    UART_Start() ;

    splash() ;

    dump_memory() ;

   

    for(;;)

    {

        prepare_source(i) ;

        DMA_Trigger() ;

        CyDelay(1) ;

        int_out_Write(0) ;

        dump_memory() ;

        i = (i + 1) % 0x100 ;

        CyDelay(1000) ;

    }

}

===================

moto

0 Likes
1 Solution
AikoO_51
Moderator
Moderator
Moderator
100 sign-ins First question asked 50 solutions authored

It’s necessary this API, CyIntEnable(CYDMA_INTR_NUMBER), to enable DMA interrupt other than CyGlobalIntEnable.

I tried the API, and then the ISR was worked.

Also you can make sure of it on code example, DMA_UART_PSoC401.

Please refer to the code example.

Aiko Ohtaka
Infineon Technologies

View solution in original post

0 Likes
4 Replies
AikoO_51
Moderator
Moderator
Moderator
100 sign-ins First question asked 50 solutions authored

It’s necessary this API, CyIntEnable(CYDMA_INTR_NUMBER), to enable DMA interrupt other than CyGlobalIntEnable.

I tried the API, and then the ISR was worked.

Also you can make sure of it on code example, DMA_UART_PSoC401.

Please refer to the code example.

Aiko Ohtaka
Infineon Technologies
0 Likes
lock attach
Attachments are accessible only for community members.
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Dear AikoO_51-san,

Thank you very much for your answer!

I modified my program as below and now I can observe that the interrupt is being generated!

Oscilloscope waveform

Red: int_out (driven from FW)

Yellow: TRO (Tr_out)

IMG_4517.JPG

main.c

===========

#include "project.h"

#include "stdio.h"

#define STR_BUF_LEN 54

char str[STR_BUF_LEN+1] ;

void print(char *str)

{

    UART_UartPutString(str) ;

}

void cls(void)

{

    print("\x1b[2J\x1b[;H") ;

    CyDelay(1) ;

}

void splash(void)

{

    cls() ;

    snprintf(str, STR_BUF_LEN, "DMA Test (%s %s)\n\r", __DATE__, __TIME__) ;

    print(str) ;

}

volatile uint8_t source[32] = { 0u } ;

uint8_t destination[32] ;

CY_ISR(my_dma_isr)

{

    int_out_Write(0) ;

}

void dump_memory(void)

{

    int i ;

    print("Src: ") ;

    for (i = 0 ; i < 10 ; i++ ) {

        snprintf(str, STR_BUF_LEN, "%02X ", source) ;

        print(str) ;

    }

    print("\n\r") ;

    print("Dst: ") ;

    for (i = 0 ; i < 10 ; i++ ) {

        snprintf(str, STR_BUF_LEN, "%02X ", destination) ;

        print(str) ;

    }

    print("\n\r\n\r") ;

    CyDelay(10) ;

}

void prepare_source(int offset)

{

    int i ;

    for (i = 0 ; i < 8 ; i++ ) {

        source = i + offset ;

    }

}

int main(void)

{

    int i = 0 ;

  

    CyGlobalIntEnable; /* Enable global interrupts. */

  

    CyIntEnable(CYDMA_INTR_NUMBER) ; // <--- NEW

    DMA_Start((void*)source, destination) ;

    DMA_SetInterruptCallback(my_dma_isr) ;

    UART_Start() ;

    splash() ;

    dump_memory() ;

  

    for(;;)

    {

        prepare_source(i) ;

        int_out_Write(1) ;

        DMA_Trigger() ;

      

        dump_memory() ;

        i = (i + 1) % 0x100 ;

        CyDelay(1000) ;

    }

}

===========

Best Regards,

30-Oct-2020

Motoo Tanaka

0 Likes
lock attach
Attachments are accessible only for community members.
MotooTanaka
Level 9
Level 9
Distributor - Marubun (Japan)
First comment on blog Beta tester First comment on KBA

Hi,

Actually, what I wanted to test was

(1) When a descriptor has multiple element(s) (for example 😎

(2) Transfer mode is element per trigger

(3) If the interrupt will be generated at the end of descriptor or at each transfer.

So I modified the program as below

main.c

=======================

#include "project.h"

#include "stdio.h"

#define STR_BUF_LEN 54

char str[STR_BUF_LEN+1] ;

void print(char *str)

{

    UART_UartPutString(str) ;

}

void cls(void)

{

    print("\x1b[2J\x1b[;H") ;

    CyDelay(1) ;

}

void splash(void)

{

    cls() ;

    snprintf(str, STR_BUF_LEN, "DMA Test (%s %s)\n\r", __DATE__, __TIME__) ;

    print(str) ;

}

volatile uint8_t source[32] = { 0u } ;

uint8_t destination[32] ;

volatile int dma_done_flag = 0 ;

CY_ISR(my_dma_isr)

{

    dma_done_flag = 1 ;

}

void dump_memory(void)

{

    int i ;

    print("Src: ") ;

    for (i = 0 ; i < 10 ; i++ ) {

        snprintf(str, STR_BUF_LEN, "%02X ", source) ;

        print(str) ;

    }

    print("\n\r") ;

    print("Dst: ") ;

    for (i = 0 ; i < 10 ; i++ ) {

        snprintf(str, STR_BUF_LEN, "%02X ", destination) ;

        print(str) ;

    }

    print("\n\r\n\r") ;

    CyDelay(10) ;

}

void prepare_source(int offset)

{

    int i ;

    for (i = 0 ; i < 8 ; i++ ) {

        source = i + offset ;

    }

}

int main(void)

{

    int i = 0 ;

    int j = 0 ;

   

    CyGlobalIntEnable; /* Enable global interrupts. */

   

    CyIntEnable(CYDMA_INTR_NUMBER) ;

    DMA_Start((void*)source, destination) ;

    DMA_SetInterruptCallback(my_dma_isr) ;

    UART_Start() ;

    splash() ;

    dump_memory() ;

   

    for(;;)

    {

        prepare_source(i) ;

        while(dma_done_flag == 0) {

            DMA_Trigger() ;

            CyDelayUs(1) ;

        }

        int_out_Write(1) ;

        CyDelayUs(1) ;

        int_out_Write(0) ;

        dma_done_flag = 0 ;

       

        dump_memory() ;

        i = (i + 1) % 0x100 ;

        CyDelay(1000) ;

    }

}

=======================

The result oscilloscope wave form was

IMG_4518.JPG

So I could confirm that the interrupt was generated at the end of the descriptor not at the end of each tranfer.

moto

AikoO_51
Moderator
Moderator
Moderator
100 sign-ins First question asked 50 solutions authored

That's good to hear.

Thank you for sharing your escalation.

Aiko Ohtaka
Infineon Technologies