EDMA interrupts

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

EDMA interrupts

661 Views
LuigiV
Contributor III

I need your help again...

I'm developing a new project, I have to interface an external codec (but first I'll use the WM8960) and I need to transmit and receive blocks of 128 word(32 bits) in a continuous mode to and from the CODEC.

I use the DMA channel 1 to receive and the DMA channel 0 to transmit; I configured the TCD registers but I don't know how to link the interrupt routines to the DMA; this is the DMA setting:

 

edma_tcd_t DMAmystruct;

edma_tcd_t *mytcd;

mytcd=&DMAmystruct;

 

//DMA0_IRQn interrupt handler transmit

void INT_0_IRQHANDLER(void){

EDMA_ClearChannelStatusFlags((DMA_Type *)0x400E8000, 0, kEDMA_InterruptFlag);

 

 

}

 

//DMA0_IRQn interrupt handler receive

void INT_1_IRQHANDLER(void){

EDMA_ClearChannelStatusFlags((DMA_Type *)0x400E8000, 1, kEDMA_InterruptFlag);

 

 

}

 

//DMA channel 1, receive

DMAmystruct.SADDR=(__IO uint32_t)((uint32_t)I2S1_RDR0);

DMAmystruct.SOFF=0;

DMAmystruct.ATTR=0x22;

DMAmystruct.NBYTES=4;

DMAmystruct.SLAST=0;

DMAmystruct.DADDR=(__IO uint32_t)i2s2_rx_buffer;

DMAmystruct.DOFF=4;

DMAmystruct.CITER=256;

DMAmystruct.DLAST_SGA=-1024;

DMAmystruct.BITER=256;

DMAmystruct.CSR=0x02; //Interrupt on major loop completion

 

EDMA_InstallTCD(mydmabase,1,mytcd); //Install I2S receive DMA channel 1

 

//DMA channel 0, transmit

DMAmystruct.SADDR=(__IO uint32_t)i2s2_rx_buffer;

DMAmystruct.SOFF=4;

DMAmystruct.ATTR=0x22;

DMAmystruct.NBYTES=4;

DMAmystruct.SLAST=-1024;

DMAmystruct.DADDR=(__IO uint32_t)((uint32_t)I2S1_TDR0);

DMAmystruct.DOFF=0;

DMAmystruct.CITER=256;

DMAmystruct.DLAST_SGA=0;

DMAmystruct.BITER=256;

DMAmystruct.CSR=0x02; //Interrupt on major loop completion

 

EDMA_InstallTCD(mydmabase,0,mytcd); //Install I2S transmit DMA channel 0

 

Thanks, Luigi

Labels (1)
0 Kudos
Reply
2 Replies

642 Views
EdwinHz
NXP TechSupport
NXP TechSupport

Hi @LuigiV,

Have you looked into the provided example codes from the SDK? You could link by using software based transfer requests, which can be achieved by setting TCDn_CSR[START], as described on section "6.6.1 eDMA initialization". This is also done by the "void EDMA_StartTransfer(edma_handle_t *handle)" routine from the eDMA driver API.

Let me know if this helps.

BR,
Edwin.

0 Kudos
Reply

636 Views
LuigiV
Contributor III

Thank you EdwinHz,

I'm trying to have a more direct approach to the MPU registers...I'm primarily a "hardware man" and I need to develop firmware too, but I'm not that good...

For example I would need to better understand how the handles work (any help ?)...I'm trying to avoid them now.

This is my solution, but I don't know if it is right:

#define IRQ_DMA_CH0 0

#define IRQ_DMA_CH1 1

void(*volatile _VectorsRam[80+16])(void);  //Table 4-2. CM7 domain interrupt summary, IMXRT1010-reference.pdf p.38

static inline void attachInterruptVector(uint16_t irq, void (*function)(void)) __attribute__((always_inline, unused));

static inline void attachInterruptVector(uint16_t irq, void (*function)(void)) { _VectorsRam[irq + 16] = function; asm volatile("": : :"memory"); }

 

//An interrupt routine can be run when the DMA channel completes the entire transfer, and also optionally when half of the transfer is completed

void DMAattachInterrupt(void (*isr)(void), uint16_t channel) {

_VectorsRam[channel+IRQ_DMA_CH0+16]=isr;

NVIC_ENABLE_IRQ(IRQ_DMA_CH0+0);

}

main(){

...

...

...

DMAattachInterrupt(INT_0_IRQHANDLER, 0); //Attach interrupt channel 1

DMAattachInterrupt(INT_1_IRQHANDLER, ); //Attach interrupt channel 1

...

...

}

 Luigi

0 Kudos
Reply