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
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.
Thank you EdwinHz,
I'm trying to have a more direct approach to the MPU registers...I'm primarily a "hardware man"
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