Hi all,
First of all, as a newbie, I put the subject of my message as my alias... Hum, does anybody has a solution for that?
Now lets talk about my problem.
I am using the M52259EVB and I am trying to use DMA0 transfers to UART1, and it doesn't work. The point is that when I use the debugger and that I look at the DMA0's register (such as SAR0, DAR0, DCR0...) values, I can see that they always stay at 0. I have been through the forum, searching for DMA similar problems but it was unsuccessful. The UART1 works well.
I am using Codewarrior IDE 5.9.0 .
Here is the code I use to initialize DMA0 (I followed the instructions written in the MCF52259 reference manual):
/* Initialize RAMBAR */
asm {
move.l #0x20000221,d0
movec d0,RAMBAR
}
........
DMAREQC |= DMAREQC_DMAC00_BITMASK; //maps UART1 transmit
DMAREQC |= DMAREQC_DMAC02_BITMASK;
DMAREQC |= DMAREQC_DMAC03_BITMASK;
PACR1 |= PACR1_ACCESS_CTRL00_BITMASK; //Enable DMA access to the UART1
PACR1 |= PACR1_ACCESS_CTRL01_BITMASK;
DCR0 |= DCR0_START_BITMASK;
DCR0 |= DCR0_CS_BITMASK; //cycle steal mode
DCR0 |= DCR0_SSIZE0_BITMASK; //one byte size
DCR0 |= DCR0_DSIZE0_BITMASK; //one byte size
DCR0 |= DCR0_D_REQ_BITMASK; //disable external requests when BCR reaches zero
SAR0 = (uint32) &source; //address of the source data
DCR0 |= DCR0_SINC_BITMASK; //increment source pointer
DAR0 = (uint32) &UTB0; //address of the UART transmit buffer
DCR0 &= !DCR0_DINC_BITMASK; //clear DINC
BCR0 |= BCR0_BCR4_BITMASK; //Number of bytes to transmit
DCR0 |= DCR0_EEXT_BITMASK; //start data transfers
Once again, when I am using the debugger to watch at DMA0 registers their values do not change.... Is there any write access to allow in addition to enable DMA access to UART1?
Thanks in advance for any answers that may help me to figure out what is my problem...
PS: I already have succeed in using UART, SPI, PIT, and interrupts, so I am an improved newbie
Thomas
Hi Thomas
Please check the sequence against the following one which works for transmission on UART1 (note that it uses DMA channel 1 and not 0):
1) DMAREQC = 0x0000000d; [select DMA matrix for UART 1 Tx on DMA channel 1]
2) PACR2 = 0x04; [enable DMA access to UART1]
3) SAR1 = address of data to be sent
4) DAR1 = address of UART1 TX register (it looks as though you may have set yours to the UART0 tx register)
5) BCR1 = 0x01000000; to clear all status flags
6) BCR1 = the number of bytes to be transferred
7) DCR1 = 0xe0520000; to configure the channel and prepare to start
8) Enable the UART transmitter - UCR1 = 0x04; to start UART transmission
Finally note that the UART needs to be configured beforehand in the same way as for polling or interrupt operation.
Usually the DMA channel's interrupt is used to signify the end of the transmission, which may reset the DMA channel and disable the UART's transmitter as well as reetting the DMA channel's status ready for the next transfer.
Regards
Mark
Hi,
Once again thx for those answers.
I tried what you suggested. I still got the same problem... When I use the debugger in order to run the program step by step and look at registers' values it is still the same: for the first two registers DMAREQC and PACR2 it is ok, their values change, but then SAR1 and the other DMA1's registers the value do not change and stay at 0...
I tried to send a technical request to freescale support but I got no answer...
Thanks,
Thomas
Hi Thomas
Unfortunately the reason for the problem doesn't seem to be visible so the only thing that I can sugget is that you try the driver from the uTasker project. This will run interrupt or DMA modes on all of the UARTs - it also allows you to simulate the operation and so better debug things. In addition it includes TCP/IP, USB device stacks, several file systems for internal and external Flash and SD cards plus drivers for most peripherals and several boot loaders - all simulated to speed up developments, debugging and testing.
If you are not working through the peripherals as a hobby/learning project this will save you a lot of time - it is designed for efficiency and small footprint so will generally allow the maximum to be achieved with the chip in question.
In case you have to use your existing base in a project with critical deadlines, the uTasker project offers design/consulting services to solve such problems in a minimum of time. Debugging/corrections for your project should be possible within 24 hours if you contact the Coldfire email address on the web site and send the existing project code.
Regards
Mark
Hi,
Thanks for the time you spent on my problem.
I'll have a look at uTasker project as you suggest.
Thanks
Thomas
I typed "uart dma" into the search box, and found AN2168, which might be useful:
http://cache.freescale.com/files/netcomm/doc/app_note/AN2168.pdf?fsrch=1&sr=4
It isn't for your CPU, but it should be close enough.
You may have to trigger the first interrupt to start the DMA. So you probably have to set up the DMA controller, then manually transmit ONE BYTE. Either that or you have to have the "uart transmit interrupt enable" last to generate the DMA request.
Tom
Hi,
Thanks a lot, i'll have a look at it!
Thomas
Hi
When DMA doesn't work you should usually find that there is an indication of the reasons for the problem in its error status register.
Check for example that the DMA controller is allowed to access SRAM (the usual source/destination) since this is not enabled by default:
GPACR0 = SUP_USER_FULL_ACCESS; // enable peripheral SRAM access
Regards
Mark
Reference: http://www.utasker.com/docs/uTasker/uTaskerUART.PDF
Hi,
Thanks for those answers.
I have already looked at the status register and the value is always 0x00.
I will try to check about allowing the DMA controller to access SRAM, even if it is something that I was aware of....
But the most disturbing things is that i am not able to modify DMA registers.
Hi
Check that the DMA is powered up (clocked)
PPMRC = 4;
If a peripheral is not clocked an exception usually results when an access attempt is made.
Regards
Mark
Hi,
The DMA is powered up.
I don't see what I did wrong....
Thanks for your answer,
Thomas