This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TMS320C6424 EDMA3 access to the buffer

Is it possible to get access to the buffer during EDMA3 DMA data transfer?

The situation is as follows: EDMA3 fill the buffer 16 kilobytes. I'm at an arbitrary time has come forward to reading the data. At the moment I can not do it. When you try to access the buffer with which works EDMA3 transfer of data stops. How to get access to the buffer and if this is possible at all?

  • Vitaliy

    How are you trying to access the buffer that is being accessed by EDMA3? Where is the buffer located in the c6424 memory?

    In general if multiple masters (say EDMA3 TCx and DSP) are trying to access the same end point (buffer), then the system interconnect arbitrates requests based on the priority of the master ( Master/bus priorities are discussed in pg 83 in the datasheet). The priorities are configurable , but by default priority for CPU accesses are lower then that for EDMA3 TC accesses. You could try to reconfigure the priority (as a test) to make the CPU priority higher or equal to the EDMA3 TC priorities, and see if it helps.

    Vitaliy said:
    When you try to access the buffer with which works EDMA3 transfer of data stops.

    Are you saying when you try to access the buffer, it stops your EDMA3 transfers in between? This should not happen.

    Regard

    Mukul

  •  

     

    Buffer located in DDR2 memory. EDMA3 used to transfer of data from UART to buffer in DDR2 memory.

    I'm read this buffer by CPU in timer interrupt.

     

    When you try to access the buffer with which works EDMA3 transfer of data stops.

    YES.   Transfer of data stops.

     

    unsigned char  TmpBuff[16384];

     

    Init edma:

    Edma3ccRegsOvly->PARAMSET[22].OPT = 0x00100000;
    Edma3ccRegsOvly->PARAMSET[22].SRC = 0x01C20000;
    //Принимаем 16384 байт
    Edma3ccRegsOvly->PARAMSET[22].A_B_CNT = 0x40000001;
    //Адрес начала бфера приема
    Edma3ccRegsOvly->PARAMSET[22].DST = (Uint32) TmpBuff;
    //Edma3ccRegsOvly->PARAMSET[22].DST = 0x80000000;
    //При каждом событии адрес приемника инкрементируется
    Edma3ccRegsOvly->PARAMSET[22].SRC_DST_BIDX = 0x0001<<16 | 0x0000;
    //При завершении приема - копирование данных из 65 канал
    Edma3ccRegsOvly->PARAMSET[22].LINK_BCNTRLD = 0x0000<<16 | 0x4820;//0x4820
    Edma3ccRegsOvly->PARAMSET[22].SRC_DST_CIDX = 0x0000<<16 | 0x0000;
    Edma3ccRegsOvly->PARAMSET[22].CCNT = 0x0000<<16 | 0x0001;

    //Содрежимое 65 канала копируется в 22 канал после завершения работы последнего
    Edma3ccRegsOvly->PARAMSET[65].OPT = 0x00100000;
    Edma3ccRegsOvly->PARAMSET[65].SRC = 0x01C20000;
    Edma3ccRegsOvly->PARAMSET[65].A_B_CNT = 0x40000001;
    Edma3ccRegsOvly->PARAMSET[65].DST = (Uint32) TmpBuff;
    //Edma3ccRegsOvly->PARAMSET[22].DST = 0x80008000;
    Edma3ccRegsOvly->PARAMSET[65].SRC_DST_BIDX = 0x0004<<16 | 0x0000;
    Edma3ccRegsOvly->PARAMSET[65].LINK_BCNTRLD = 0x0000<<16 | 0x4820;
    Edma3ccRegsOvly->PARAMSET[65].SRC_DST_CIDX = 0x0000<<16 | 0x0000;
    Edma3ccRegsOvly->PARAMSET[65].CCNT = 0x0000<<16 | 0x0001;

    //Edma3ccRegsOvly->EESR = 0x0040<<16 | 0x0000;
    //Разрешение обработки событий от 22 канала (UART)
    Edma3ccRegsOvly->EESR = 0x00400000;
    //Разрешение прерываний от нулевого канала 0
    Edma3ccRegsOvly->IESR = 0x0000<<16 | 0x0001;

    extern "C" interrupt void Timer0_isr(void)
    {

    unsigned char   readed;

    readed=TmpBuff[0];   // if this code present - no more DMA transfer from UART to TmpBuff
    }


    And another question:
    Shipping UART-> CPU-> buffer cache L2-> EDMA3-> UART operates normally 
    Shipping UART-> CPU-> buffer in DDR2-> EDMA3-> UART not working correctly - the symbols are transmitted erroneous. What can be the reason?

     //#pragma DATA_SECTION(".mydata") //L2 or DDR2
    unsigned char UartRxBuff[256];  
    unsigned char* pointer = UartRxBuff;
    EDMA init:

    Edma3ccRegsOvly->PARAMSET[10].OPT=0x00101000;
    Edma3ccRegsOvly->PARAMSET[10].SRC=(Uint32)&UartRxBuff;
    Edma3ccRegsOvly->PARAMSET[10].A_B_CNT=0x00010001;
    Edma3ccRegsOvly->PARAMSET[10].DST=0x01C20000;
    Edma3ccRegsOvly->PARAMSET[10].SRC_DST_BIDX=0x0000<<16 | 0x0000;
    Edma3ccRegsOvly->PARAMSET[10].LINK_BCNTRLD=0x0000<<16 | 0x4840;
    Edma3ccRegsOvly->PARAMSET[10].SRC_DST_CIDX=0x0000<<16 | 0x0000;
    Edma3ccRegsOvly->PARAMSET[10].CCNT=0x0000<<16 | 0x0001;

    Edma3ccRegsOvly->PARAMSET[66].OPT=0x00101000;
    Edma3ccRegsOvly->PARAMSET[66].SRC=(Uint32)&UartRxBuff;
    Edma3ccRegsOvly->PARAMSET[66].A_B_CNT=0x00010001;
    Edma3ccRegsOvly->PARAMSET[66].DST=0x01C20000;
    Edma3ccRegsOvly->PARAMSET[66].SRC_DST_BIDX=0x0000<<16 | 0x0000;
    Edma3ccRegsOvly->PARAMSET[66].LINK_BCNTRLD=0x0000<<16 | 0x4840;
    Edma3ccRegsOvly->PARAMSET[66].SRC_DST_CIDX=0x0000<<16 | 0x0000;
    Edma3ccRegsOvly->PARAMSET[66].CCNT=0x0000<<16 | 0x0001;
    Edma3ccRegsOvly->EESR |= 0x0000<<16 | 0x0400;
    Edma3ccRegsOvly->IESR |= 0x0000<<16 | 0x0002;

    extern "C" interrupt void Uart_ISR(void)
    {
    UartRxBuff[0] = uart1Regs->RBR; 
    Edma3ccRegsOvly->ESR |= 0x0000<<16 | 0x0400;

    }

    extern "C" interrupt void Edma_ISR(void)

    if (Edma3ccRegsOvly->IPR == 0x02)
    {
    Edma3ccRegsOvly->ICR = 0x00000002;
    }
    }

  • Hi Vitaliy

    I could not spend any time on this post today, will look at this more tomorrow, seems like you later updated the post with code snippet, I didn't realize that those are there when your original post showed up.

    I did have some quick questions on this

    1) For your original query, you mentioned that the CPU could not access the buffer that was being used by the EDMA to transfer 16KBytes. Is that really true , or is that problem statement really that when you try to access the same buffer via CPU in your timer ISR , your EDMA transfers from UART stop working?

    2) Have you confirmed that you don't have any conflicts with your interrupt setup between the timer interrupt and the EDMA completion interrupt? Or alternatively, if you didn't issue a read to the buffer in your timer ISR, does your EDMA transfers continue to work?

    3) When the UART-EDMA transfers stop working, do you see any UART error bits being set?

    For your second issue,

    1) Are there other things going on in the system besides the UART to DDR2 via EDMA?

    2 ) Is the DDR2 PBBPR register value (offset 0x20 in the MMR space) set to 0x20 ?

    3) What is the UART baud rate?

    Finally, since you mentioned that the EDMA transfers for your original post are between SRC= UART , DST= memory, I don' t think you have a "contention" issue between EDMA accesses vs CPU accesses to the same memory buffer, because in general the UART transfers are going to be very slow (not a continous 16 KB transfer like in a case of EDMA doing a memory to memory transfer) , so I don't think the EDMA accesses to your UART receive buffer are going to be that high, so as to block the CPU from accessing the same memory in a noticeable manner.

    Regards

    Mukul

  • To make things clear - test projects here: http://www.mediafire.com/?mzytj5kirq2 Dir v1 - first issue, dir v2 - second issue

    1.1 CPU CAN access the buffer that was being used by the EDMA. But the side effect of this access  is that the EDMA stop working.

    v1\Timer.c line 116: currentChar = TmpBuff[UartRP++];  if comment this read - edma works.

    1.2 EDMA and timer interrupt used a different interrupts number. No conflict.

    .align 32
    .def INT5_V
    INT5_V: ; Maskable Interrupt #5
    .ref _Timer0_isr
    push b0
    mvkl .s2 _Timer0_isr,b0
    mvkh .s2 _Timer0_isr,b0
    b .s2 b0
    pop b0, 4
    NOP
    NOP
    NOP

    .align 32
    .def INT6_V
    INT6_V: ; Maskable Interrupt #6
    .ref _Edma_ISR
    push b0
    mvkl .s2 _Edma_ISR,b0
    mvkh .s2 _Edma_ISR,b0
    b .s2 b0
    pop b0, 4
    NOP
    NOP
    NOP

    1.3 When the UART-EDMA transfers stop working, UART error bits don't set.

    2.1 System is free. It's just a test. EDMA3, UART, TIMER no more devices are used.

    2.2 DDR2 PBBPR register 0x20000020 set to 0x20 do not give any results.

    2.3  UART baud rate is 9600.

  • The issue is closed. This lack of processor architectures of transparency with second-level cache. Manual control of L2 depressing = (

  • Hi Vitaliy

    Glad to hear that the issue is closed. Sorry for not being able to provide any significant/timely assistance on this.
    If possible , for the interest of others on the forum, can you summarize what fixed the issue? Are you saying you were having cache coherency issues or was L2 MAR bits for caching DDR2 memory were not enabled?

    Regards

    Mukul


  • The corresponding bit MAR naturally set to 1. Otherwise, DDR2 runs too slowly.
    To solve the problem before accessing the data forcibly updates the data in L2 cache.

    Uint32 savedUartWP = (Uint32)Edma3ccRegsOvly->PARAMSET[22].DST - (Uint32)TmpBuff;
    unsigned char currentChar = 0;

    //Считываем все данные из буфера
    while ((savedUartWP - UartRP) != 0)
    {
    Uint32 size = savedUartWP - UartRP;
    Uint32 address = (Uint32)TmpBuff + UartRP;
    CACHE_invL2((Uint32*)address,size,CACHE_WAIT);  //                           It is absolutely necessary T_T
    currentChar = TmpBuff[UartRP++];
    Read_Buff[localRP++] = currentChar;
    if (currentChar == '\n' || localRP > TRANSMIT_LENGTH - 1 || currentChar == 0x0D)
    {
    Enqueue_to_uart(Read_Buff, localRP);
    localRP = 0;
    }
    UartRP&=(InBuffLength-1);
    }

    and before start EDMA3 transfer absolutely necessary:

    CACHE_wbL2((Uint32*)ujob_ptr_tmp->ucBlockDataPtr,ujob_ptr_tmp->uiSize,CACHE_WAIT);  //                           It is absolutely necessary T_T

    Edma3ccRegsOvly->PARAMSET[23].OPT = 0x00101000;
    Edma3ccRegsOvly->PARAMSET[23].SRC = (Uint32)ujob_ptr_tmp->ucBlockDataPtr;
    Edma3ccRegsOvly->PARAMSET[23].A_B_CNT = ((Uint16)ujob_ptr_tmp->uiSize)<<16 | 0x0001;
    //Edma3ccRegsOvly->PARAMSET[23].A_B_CNT = 0x0001<<16 | 0x0001;
    Edma3ccRegsOvly->PARAMSET[23].DST = 0x01C20000;
    Edma3ccRegsOvly->PARAMSET[23].SRC_DST_BIDX = 0x0000<<16 | 0x0001;
    Edma3ccRegsOvly->PARAMSET[23].LINK_BCNTRLD = 0x0000<<16 | 0xFFFF;
    Edma3ccRegsOvly->PARAMSET[23].SRC_DST_CIDX = 0x0000<<16 | 0x0000;
    Edma3ccRegsOvly->PARAMSET[23].CCNT = 0x0000<<16 | 0x0001;