MPC5566: UART RX DMA doesn't put in destination buffer

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 

MPC5566: UART RX DMA doesn't put in destination buffer

ソリューションへジャンプ
2,346件の閲覧回数
zwilcox
Contributor IV

I'm attempting to set the DMA for the RX of the UART/ESCI.

The DMA finishes but the destination buffer never received the that was received.

Why is it the DMA finishes but doesn't put the data in the destination buffer address?

Edit:  I can receive over the uart by polling the CR1 register or interrupting when the UART received.

Edit:  After the DMA is finished, I print of the status register.  The status register is 0xE0_01_C0_00

// DMA channel used for ESCI
#define DMA_ESCIA_TX 18
#define DMA_ESCIA_RX 19

#define DMA_ESCIB_TX 34
#define DMA_ESCIB_RX 35

void esci_init_default(struct ESCI_tag pEsci)

    pEsci->CR1.R = 0x0005000C;
            // SCI Baud rate : 1000.0000 khz
            // Loop Selected : Disable
            // Receiver Source : Transmitter connected Internal
            // Data Format : 8 bits long
            // Wake-up condition : Idle Line wakeup
            // Idle Line Type : Count at Start bit
            // Parity Bit : Disable
            // Parity Type : Even
            // Transmit Interrupt Enable : Disable
            // Transmission Complete Interrupt : Disable
            // Receive Full Interrupt : Enable
            // Idle Line Interrupt : Disable
            // Transmitter : Enable
            // Receiver : Enable
    uint8_t tx_channel = pEsci == &ESCI_A ? DMA_ESCIA_TX : DMA_ESCIB_TX;
    uint8_t rx_channel = pEsci == &ESCI_A ? DMA_ESCIA_RX : DMA_ESCIB_RX;

    EDMA.TCD[tx_channel].DONE = 1;
    EDMA.TCD[rx_channel].DONE = 1;

    pEsci->CR2.R = 0x2C00;  // enable DMA
                // Fast Bit Error detection : Disable
            // Bit-Error Stop : Enable
            // Bit Error Interrupt : Disable
            // Activate Rx DMA Channel : Enable
            // Activate Tx DMA Channel : Enable
            // Break Transmit Character Length : 10 bit
            // Bit Error Sample Mode : RT clock 9
            // SCI bit error stop : Disable
            // Overrun error Interrupt : Disable
            // Noise flag Interrupt : Disable
            // Frame Error Interrupt : Disable
            // Parity flag Interrupt : Disable
     pEsci->LCR.R = 0x00000000;
            // LIN bus wake-up : Enabled
            // Wake-up delimiter time : 4
            // LIN Debug Mode : Disabled
            // LIN Mode : Disabled
            // Double Stop Flags : Disabled
            // Activate Parity Generation : Disabled
            // RxREG Ready Interrupt : Disabled
            // TxREG Ready Interrupt : Disabled
            // Rx Wakeup Interrupt : Disabled
            // Slave timeout error Interrupt : Disabled
            // Physical bus error Interrupt : Disabled
            // CRC Error Interrupt : Disabled
            // Checksum error Interrupt : Disabled
            // Frame Complete Interrupt : Disabled
            // Overflow Interrupt : Disabled
}

void EDMA_ESCI_Receive(struct ESCI_tag* eSCI, uint8_t *bufptr, uint32_t count)
{

  uint8_t rx_channel = eSCI == &ESCI_A ? DMA_ESCIA_RX : DMA_ESCIB_RX;
  EDMA.TCD[rx_channel].SADDR = (vuint32_t)&eSCI->DR + 1; // Load address of source data 
  EDMA.TCD[rx_channel].SSIZE = 0;                        // Read 2**0 = 1 byte per transfer 
  EDMA.TCD[rx_channel].SOFF = 0;                         // Do not increment source addr
  EDMA.TCD[rx_channel].SLAST = 0;                        // After major loop, reset src addr
  EDMA.TCD[rx_channel].SMOD = 0;                         // Source modulo feature not used 

  EDMA.TCD[rx_channel].DADDR = (vuint32_t)bufptr;        // Load address of destination 
  EDMA.TCD[rx_channel].DSIZE = 0;                        // Write 2**0 = 1 byte per transfer 
  EDMA.TCD[rx_channel].DOFF = 1;                         // Increment destination addr 
  EDMA.TCD[rx_channel].DLAST_SGA = 0;                    // After major loop, no dest addr change
  EDMA.TCD[rx_channel].DMOD = 0;                         // Destination modulo feature not used 
  
  EDMA.TCD[rx_channel].NBYTES = 1;                       // Transfer 1 byte per minor loop 
  EDMA.TCD[rx_channel].BITER = count;                    // Number of minor loop iterations 
  EDMA.TCD[rx_channel].CITER = count;                    // Number of minor loop iterations 
  EDMA.TCD[rx_channel].DREQ = 1;                        // Disable channel when major loop is done
  EDMA.TCD[rx_channel].INTHALF = 0;                     // Interrupts is not used 
  EDMA.TCD[rx_channel].INTMAJ = 1;                      // Interrupt is enabled
  EDMA.TCD[rx_channel].MAJORELINK = 0;                  // Dynamic program is not used 
  EDMA.TCD[rx_channel].ESG = 0; 
  EDMA.TCD[rx_channel].BWC = 0;                          // Default bandwidth control- no stalls 
  EDMA.TCD[rx_channel].START = 0;                        // Initialize status flags 
  EDMA.TCD[rx_channel].DONE = 0;
  EDMA.TCD[rx_channel].ACTIVE = 0;
  
  // Enable the rx_channel 
  EDMA.SERQR.R = rx_channel;
}

int EDMA_ESCI_IsRxDMADone(struct ESCI_tag* eSCI)
{

    uint8_t rx_channel = eSCI == &ESCI_A ? DMA_ESCIA_RX : DMA_ESCIB_RX;

  return (EDMA.TCD[rx_channel].DONE == 1);
}

int esci_setBaudRate(struct ESCI_tag* pEsci , int baudRate)
{
    if (pEsci == NULL) return -1;

    pEsci->CR1.B.SBR = (BD_CPU_CLK_HZ / (16 * baudRate)); //set baud rate

    return ((BD_CPU_CLK_HZ)/(16 * pEsci->CR1.B.SBR));
}

#define COMMAND_BUFFER_SIZE 3
uint8_t  dma_buffer[COMMAND_BUFFER_SIZE] = {0};

void main(void)
{
   esci_init_default(&ESCI_A);
   esci_setBaudRate(&ESCI_A, 9600);  // works

   memset(dma_buffer, 0x55, COMMAND_BUFFER_SIZE);
   EDMA_ESCI_Receive(&ESCI_A, dma_buffer, 1);
   while(1)
   { 
     if(EDMA_ESCI_IsRxDMADone(&ESCI_A))
     {
         WriteUARTN(&ESCI_A.SR.R, 4);
         //this just prints whatever was memset :(
         WriteUARTN(dma_buffer, COMMAND_BUFFER_SIZE);
  memset(dma_buffer, 0x55, COMMAND_BUFFER_SIZE);
         EDMA_ESCI_Receive(&ESCI_A, dma_buffer, 1); 
      }
   }
}


‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
0 件の賞賛
返信
1 解決策
2,185件の閲覧回数
zwilcox
Contributor IV

Thanks for your reply.

Apparently it was a caching issue.   Clearing the cache resolved it :smileyhappy:

元の投稿で解決策を見る

0 件の賞賛
返信
2 返答(返信)
2,185件の閲覧回数
lukaszadrapa
NXP TechSupport
NXP TechSupport

Hi,

I'm not sure what's wrong on your side but this minimalist code is working as expected. Loop mode is used in this test:

unsigned char rec_data[10];

void ESCI_A_Init(void)
{  
  ESCI_A.CR1.B.SBR = 64000000/16/9600;  
  ESCI_A.CR1.B.LOOPS = 1;  
  ESCI_A.CR1.B.TE = 1;  
  ESCI_A.CR1.B.RE = 1;  
  ESCI_A.CR2.R = 0x2800;              
}

void EDMA_ESCI_Receive(void)
{
  uint8_t rx_channel = 19;
 
  EDMA.TCD[rx_channel].SADDR = (vuint32_t)&ESCI_A.DR.R + 1; // Load address of source data
  EDMA.TCD[rx_channel].SSIZE = 0;                        // Read 2**0 = 1 byte per transfer
  EDMA.TCD[rx_channel].SOFF = 0;                         // Do not increment source addr
  EDMA.TCD[rx_channel].SLAST = 0;                        // After major loop, reset src addr
  EDMA.TCD[rx_channel].SMOD = 0;                         // Source modulo feature not used

  EDMA.TCD[rx_channel].DADDR = (vuint32_t)rec_data;        // Load address of destination
  EDMA.TCD[rx_channel].DSIZE = 0;                        // Write 2**0 = 1 byte per transfer
  EDMA.TCD[rx_channel].DOFF = 1;                         // Increment destination addr
  EDMA.TCD[rx_channel].DLAST_SGA = 0;                    // After major loop, no dest addr change
  EDMA.TCD[rx_channel].DMOD = 0;                         // Destination modulo feature not used
 
  EDMA.TCD[rx_channel].NBYTES = 1;                       // Transfer 1 byte per minor loop
  EDMA.TCD[rx_channel].BITER = 5;                    // Number of minor loop iterations
  EDMA.TCD[rx_channel].CITER = 5;                    // Number of minor loop iterations
  EDMA.TCD[rx_channel].D_REQ = 1;                        // Disable channel when major loop is done
  EDMA.TCD[rx_channel].INT_HALF = 0;                     // Interrupts is not used
  EDMA.TCD[rx_channel].INT_MAJ = 0;                      // Interrupt is enabled
  EDMA.TCD[rx_channel].MAJORE_LINK = 0;                  // Dynamic program is not used
  EDMA.TCD[rx_channel].E_SG = 0;
  EDMA.TCD[rx_channel].BWC = 0;                          // Default bandwidth control- no stalls
  EDMA.TCD[rx_channel].START = 0;                        // Initialize status flags
  EDMA.TCD[rx_channel].DONE = 0;
  EDMA.TCD[rx_channel].ACTIVE = 0;
 
  // Enable the rx_channel
  EDMA.SERQR.R = rx_channel;
}
    
void main(void)
{
    unsigned int j;

    ESCI_A_Init();
    EDMA_ESCI_Receive();

    //send 5 characters and receive them via DMA

    for (j=0; j< 5; j++)
    {    
        while (ESCI_A.SR.B.TDRE == 0) {}       
        ESCI_A.SR.R = 0x80000000;              /* Clear TDRE flag */
        ESCI_A.DR.B.D = (unsigned char)j;          /* Transmit 8 bits Data */        
    }

    while(1)
    {
    }
}

Regards,

Lukas

0 件の賞賛
返信
2,186件の閲覧回数
zwilcox
Contributor IV

Thanks for your reply.

Apparently it was a caching issue.   Clearing the cache resolved it :smileyhappy:

0 件の賞賛
返信