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
Hi Dirk,
You should have a look to this thread, I tried and it works fine for a coldFire V2. It could inspired you for V4 core.
Emmanuel
Hi Emmanuel,
thanks for replying.
I read that thread before.
As usual there is a little mistake that has huge consequences.
In my initialization-routine I swapped the digits of the interruptvectornumber for my dma interruptvector. So it was not setup and could not work. Now everything is fine and I can TX and RX without any problem.
Have a nice day...
vy 73
Dirk