sirlenzelot

MCF5234: UART via DMA problem

Discussion created by sirlenzelot on Feb 19, 2009
Latest reply on Feb 23, 2009 by sirlenzelot

Hi folks!

I am trying to activate UART via DMA but I'm running into some problems:

I am unable to activate DMAInterrupt on Transfer complete. Maybe I missed something.
I can see the interrupt is pending in the interrupt controller and I have setup an ISR in the vector table.

 

Here is my configuration:

 

init CPU:
CPU_SetVect(DMA_INTVECTOR::INTVECTOR1 ,UARTTXDMAISR); // Sets ISR in the Vectortable
CPU_SetVect(DMA_INTVECTOR::INTVECTOR3 ,UARTRXDMAISR);
CPU_EnableCpuInterrupt(DMA_INTVECTOR::INTVECTOR1, 0); // Mask InterruptVector
CPU_EnableCpuInterrupt(DMA_INTVECTOR::INTVECTOR3, 0);
[..]

 

init UART:
UART_ResetTX();
UART_ResetRX();
UART_SetInternalClock();
UART_SetBaudRate(115200);
UART_Mode1(_bpc=8, _paritymode=UART::NONE, _paritytype=UART::NONE, _ERR=0, _RTS=0, _INTREQ=0);
UART_Mode2(_channelmode=UART::NORMAL, _TXRTS=0, _TXCTS=0, _stopbits=1);
UART_EnableTX();
UART_EnableRX();

 

init DMA:
SCM_DMA_MasterPrivilege(2, true); // DMA 2 (DMA Controller) Master Privilege
SCM_DMA_Control(1, DMA_CHANNEL::C_UARTTX0); // DMA 1 UART0 TX
SCM_DMA_Control(3, DMA_CHANNEL::C_UARTRX0); // DMA 3 UART0 RX
SCM_DMA_ACCESS(DMA_CHANNEL::C_UART0, 4); // ACCESS User+Supervisor

 

setup TX:
DMA_ClearInterrupt(_dmachannelTX); //DSR.DONE=1
DMA_SetSourceAddress(_dmachannelTX, dmaTXbuffer);
DMA_SetDestinationAddress(_dmachannelTX, UART_TX_REGISTER);
DMA_SetByteCountRegister(_dmachannelTX, dmaTXbuffersize);
DMA_EnableExternalRequest(_dmachannelTX, true);//DCR.EEXT=1
DMA_EnableInternalInterrupt(_dmachannelTX, true);//DCR.INT=1
DMA_EnableCycleSteal(_dmachannelTX, true);//DCR.CS=1
DMA_SetSourceSize(_dmachannelTX, 1); // Byte
DMA_SetDestinationSize(_dmachannelTX, 1); // Byte
DMA_EnableSourceIncrement(_dmachannelTX, true);

 

setup RX:
DMA_ClearInterrupt(_dmachannelRX); //DSR.DONE=1
DMA_SetSourceAddress(_dmachannelRX, UART_RX_REGISTER);
DMA_SetDestinationAddress(_dmachannelRX, dmaRXbuffer);
DMA_SetByteCountRegister(_dmachannelRX, dmaTXbuffersize);
DMA_EnableExternalRequest(_dmachannelRX, true);//DCR.EEXT=1
DMA_EnableInternalInterrupt(_dmachannelRX, true);//DCR.INT=1
DMA_EnableCycleSteal(_dmachannelRX, true);//DCR.CS=1
DMA_SetSourceSize(_dmachannelRX, 1); // Byte
DMA_SetDestinationSize(_dmachannelRX, 1); // Byte
DMA_EnableDestinationIncrement(_dmachannelRX, true);

 

Output:
For each write I do:
DMA_ClearInterrupt(_dmachannelTX);
DMA_SetSourceAddress(_dmachannelTX, adr);
DMA_SetDestinationAddress(_dmachannelTX, UART_TX_REGISTER);
DMA_SetByteCountRegister(_dmachannelTX, len);
DMA_EnableExternalRequest(_dmachannelTX, true);
DMA_EnableInternalInterrupt(_dmachannelTX, true);
DMA_EnableCycleSteal(_dmachannelTX, true);
DMA_SetSourceSize(_dmachannelTX, 1); // Byte
DMA_SetDestinationSize(_dmachannelTX, 1); // Byte
DMA_EnableSourceIncrement(_dmachannelTX, true);
DMA_StartTransfer(_dmachannelTX);

 

I should do the DMA_ClearInterrupt(_dmachannelTX); in the ISR, but as I never reached the ISR, I put it here for testing.

 

 Now, every second time if I hit the ClearInterrupt thing and write to the register, I get a Configuration Error and the transfer is not committed.


My questions:
1) What did I forget to get the interrupt work?
2) How can I avoid the Configuration Error after setting DSR.DONE=1?

 

Thanks a lot

 

vy73

 

Dirk

Outcomes