- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
pins
DMA Config
Tera Term log
Note: DMA transfer seems to be done OK, except the callback is not being called.
Oscilloscope waveform
Red: int_out signal, which is supposed to be the interrupt monitoring signal
Yellow: TRO (Tr_out) signal
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
Solved! Go to Solution.
- Labels:
-
PSoC 4 Architecture
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
Infineon Technologies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
Infineon Technologies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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)
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
So I could confirm that the interrupt was generated at the end of the descriptor not at the end of each tranfer.
moto
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
That's good to hear.
Thank you for sharing your escalation.
Infineon Technologies