AnsweredAssumed Answered

BF518 problem with UART in DMA mode

Question asked by marco55 on Jan 16, 2015
Latest reply on Mar 23, 2015 by SachinV

Hello,

 

I have a problem with UART in DMA mode on a Blackfin 518F.

 

I have to communicate with a IR reader that has a simple serial interface (baudrate 9600, 8 data bits, no parity, 1 stop bit): I have to send a single byte with value "1" to read the data, and the reply of the IR reader consists of 2 bytes.

 

I'm using UART0 in DMA mode and I send the read command every 100 ms. The reply arrives within 10 - 15 ms.

 

The problem is that after some time it happens that the two bytes are read in the opposite order: I suppose that actually I read the second byte of a message plus the first byte of the following message. After some time again the two bytes "exchange" oder, and so on.

 

How can I avoid this error?

 

 

adi_int_SICSetIVG(ADI_INT_DMA8_UART0_RX, 10);//Default priority

adi_int_SICSetIVG(ADI_INT_DMA9_UART0_TX, 10);//Default priority

 

register_handler(ik_ivg10,Uart0_ISR);//DMA8 - DMA9 (Uart0 Rx/Tx)

 

adi_int_SICEnable(ADI_INT_DMA8_UART0_RX);

adi_int_SICEnable(ADI_INT_DMA9_UART0_TX);

 

*pPORTG_MUX = 0x0400;

*pPORTG_FER = 0x0600;

*pPORTGIO_DIR = 0x9980;

*pPORTGIO_INEN = 0x6000;

*pPORTGIO_POLAR = 0x0000;

*pPORTGIO_EDGE = 0x6000;

*pPORTGIO_BOTH = 0x0000;

*pPORTGIO_MASKA = 0x0000;

*pPORTGIO_MASKB = 0x6000;

 

*pDMA8_CONFIG = FLOW_STOP | WDSIZE_8 | DI_EN | SYNC | WNR;

*pDMA9_CONFIG = FLOW_STOP | WDSIZE_8 | DI_EN | SYNC;

 

Uart0Divider = Se2112Fsclk / (16 * UartBaud);

ssync();

 

*pUART0_LCR |= DLAB;

*pUART0_DLL = (unsigned char)Uart0Divider;

*pUART0_DLH = (unsigned char)(Uart0Divider >> 8);

*pUART0_LCR &= (~DLAB);

*pUART0_MCR = 0;

*pUART0_GCTL = UCEN;

*pUART0_LCR = UART0_NUM_DATA_BIT_8;

 

 

 

//Polling in Main()

if(WriteUart0)

{

     SendUart0Data((unsigned char*)&Uart0TxBuffer[0],Uart0TxBuffLen);

     while(!Uart0TxOk);

     ReceiveUart0Data((unsigned char*)&Uart0RxBuffer[0],(unsigned char)UART0_RX_BUFFER_LEN, (unsigned      short)UART0_PKT_TIMEOUT);

     WriteUart0 = false;

}

if(Uart0TimeoutExpired)//errore timeout

{

AbortUart0Receive();

ReceiveUart0Data((unsigned char*)&Uart0RxBuffer[0],(unsigned char)UART0_RX_BUFFER_LEN, (unsigned short)UART0_PKT_TIMEOUT);

Uart0TimeoutExpired = false;

}

 

 

 

 

void SendUart0Data(unsigned char *pUart0Buffer, unsigned short NumData)

{

     *pDMA9_CONFIG &= (~DMAEN);

     *pDMA9_START_ADDR = pUart0Buffer;

     *pDMA9_X_COUNT = NumData;

     *pDMA9_X_MODIFY = 1;

     ssync();

     *pDMA9_CONFIG |= DMAEN;

     Uart0TxOk = false;

     ssync();

     *pUART0_IER |= ETBEI;

}

 

void ReceiveUart0Data(unsigned char *pUart0Buffer, unsigned short NumData, unsigned short Uart0Timeout)

{

     if(Uart0Timeout > 0)

     {

          Uart0WaitingTime = (unsigned int)(Uart0Timeout * 1000) / ((unsigned int)(*pTPERIOD) / (Se2112Fcclk / 1000000));

          WaitForDataUart0 = true;

     }

     *pDMA8_CONFIG &= (~DMAEN);

     *pDMA8_START_ADDR = pUart0Buffer;

     *pDMA8_X_COUNT = NumData;

     *pDMA8_CURR_X_COUNT = 0;

     *pDMA8_X_MODIFY = 1;

     ssync();

     *pDMA8_CONFIG |= DMAEN;

     *pUART0_IER |= ERBFI;

     Uart0RxOk = false;

}

 

void AbortUart0Receive(void)

{

     *pDMA8_CONFIG &= ~DMAEN;

     *pUART0_IER &= ~ERBFI;   

     *pDMA8_CURR_X_COUNT = 0;

     WaitForDataUart0 = false;

}

 

 

void CheckTimeoutUart0(void)

{

     if((WaitForDataUart0) && (!Uart0TimeoutExpired))

     {

          if(Uart0WaitingCounter < Uart0WaitingTime)

          {

               Uart0WaitingCounter++;

          }

          else

          {

               Uart0Errors++;

               Uart0TimeoutExpired = true;

               Uart0WaitingCounter = 1;

           }

     }

     else

     {

          Uart0WaitingCounter = 1;

     }

}

 

 

 

/*****************

UART0 ISR - IVG 10

*****************/

EX_INTERRUPT_HANDLER(Uart0_ISR)

{

     unsigned short myDummyRead = 0;

     /*-------------

     DMA8 (Uart0 Rx)

     -------------*/

     if((*pSIC_ISR0 & DMA8_INT) != 0)

     {

          //Interrupt Assertion

          *pDMA8_IRQ_STATUS |= DMA_DONE;

          myDummyRead = *pUART0_IIR;

 

          *pUART0_IER &= ~ERBFI;

          *pDMA8_CONFIG &= ~DMAEN;

 

          WaitForDataUart0 = false;

 

          Uart0RxOk = true;

          Uart0Errors = 0;

     }

   

     /*-------------

     DMA9 (Uart0 Tx)

     -------------*/

     if((*pSIC_ISR0 & DMA9_INT) != 0)

     {

          //Interrupt Assertion

          *pDMA9_IRQ_STATUS |= DMA_DONE;

          myDummyRead = *pUART0_IIR;

 

          *pUART0_IER &= ~ETBEI;

          *pDMA9_CONFIG &= ~DMAEN;

 

          while((*pUART0_LSR & TEMT) == 0);

         

          Uart0TxOk = true;

     }

}

Outcomes