Tomasz Przybyla

M52259DEMOMCU - UART & DMA Problem

Discussion created by Tomasz Przybyla on May 14, 2009
Latest reply on May 14, 2009 by Mark Butcher

Hello everyone, it's my first post of this forum

 

I have no experience with Freescale microcontrollers and currently I write some small programs to get some knowledge and experience about them.

 

Now I want to prepare a small program using DMA channel 1 to send data by UART0.

 

Here is my function which in my intention configures DMA1 to send data via UART0 (based on CMRM, section 28.5.1.2):

 

void uartDMA_TX(unsigned char* data, uint32 dataLen)
{

// Enable DMA channel 1 - UART0 Tx

MCF_SCM_DMAREQC = MCF_SCM_DMAREQC_DMAC1(0x0C);   

  
// Enable interrupt on transfer completed   
MCF_INTC0_ICR10 = MCF_INTC_ICR_IL(0x3) | MCF_INTC_ICR_IP(0x3);
MCF_INTC0_IMRL &= ~(MCF_INTC_IMRL_INT_MASK10 | MCF_INTC_IMRL_MASKALL);
// DMA1 reset
MCF_DMA1_DSR = 0x01;
// Setting MPR (if not set - program behaves the same)
MCF_SCM_MPR |= 0x04;
// Setting PACRs
MCF_SCM_PACR2 |= MCF_SCM_PACR_ACCESS_CTRL1(0b110); // PACR2 - UART0
MCF_SCM_PACR1 |= MCF_SCM_PACR_ACCESS_CTRL0(0b110); // PACR1 - DMA
// SCM RAMBAR - Backdoor enable
MCF_SCM_RAMBAR |= MCF_SCM_RAMBAR_BDE;
/* DMA1 - Control register (enable interrupt on transfer complete, CycleSteal mode, Data size: 1 byte for, source increment, disable request on BCR == 0) */
MCF_DMA1_DCR = MCF_DMA_DCR_INT | MCF_DMA_DCR_CS |          MCF_DMA_DCR_SSIZE(MCF_DMA_DCR_SSIZE_BYTE) | MCF_DMA_DCR_SINC |               MCF_DMA_DCR_DSIZE(MCF_DMA_DCR_DSIZE_BYTE) | MCF_DMA_DCR_D_REQ;  
// Data source address
MCF_DMA1_SAR = (uint32)data;
// Destination address - TransferBuffer UART0
MCF_DMA1_DAR = (uint32)&MCF_UART0_UTB;
// Byte count
MCF_DMA1_BCR = MCF_DMA_BCR_BCR(dataLen);
// Start transfer
MCF_DMA1_DCR |= MCF_DMA_DCR_START;

}

I also set core RAMBAR in function void __initialize_hardware(void):

asm

{

        move.l  #0x20000221,d0
        movec   d0,RAMBAR

}

 

I also created the function handling interrupt:

__declspec(interrupt) void _DMA1_TransferComplete() which I entered into vector at position 74.

 

UART0 is initiated by function void uart_init (int,unsigned long, unsigned long) available in uart_support.c (defaulty added to my project by CodeWarrior).

 

And when I run my function by the code:

 

.....

unsigned char data[5] = {1,2,3,4,5};

uartDMA_TX(data,5);

....

 

I receive data on terminal, but it is only one byte (AFAIK it should be one in CS mode, so it's OK) with value: 0xFF. When I disable CycleSteal mode (clear CS in DCR) i receive two bytes: 0xFF 0xFF. I receive them independently from the declared bytes count to send when it's > 1. For data length == 1 I receive one byte 0xFF, for more - two bytes 0xFF.

 

And the interrupt isn't generated by DMA1.

 

I have no idea what I'm doing bad - can anybody help me?

 

Thanks.

 

Greetings from Poland.

Tom.

Outcomes