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.

CCS/TM4C1294NCPDT: About the time of reading data from ad by EPI in TM4C1294

Part Number: TM4C1294NCPDT

Tool/software: Code Composer Studio

I need a 1294epi to read the data of the time should be, how to calculate?

I use 1294 EPI in the 16 bit bus mode, read ad data, when I open the code optimization to measure time is 680ns for  8 times ,turn off code optimization once 333.3ns.

I feel more serious problem, but can not find where is the problem. Does  code optimization really matter?

my System operats at 120mhz.

  • Hi,

    I'm not clear on your question. Do you want to measure how long it takes to access the EPI? You are saying you are getting different results when you turn on/off the optimization?

    Is below pseudo code or something similar what you tried to measure the time it takes to access the EPI?

    x = SysTickValueGet();
    for (i=0;i<8;i++){
    access_EPI();
    }
    y = SysTickValueGet();
    difference = y-x;

    If above is what you use to measure how long it takes to access the EPI for 8 times then the result will be affected by the code optimization. The above code sequence consists of the function call to access_EPI() and everything else. The different compiler optimization settings can affect the final code sequence. For example, with the optimization the compiler may be able to unroll the for-loop to gain some speed at the expense of the code size.

    If you just want to measure the amount of time it spends doing only in the access_EPI() then somehow you need to remove the time the CPU spends executing the code related to everything else. Please note that the access_EPI() is a pseudo function that I'm using for illustration. The code optimization can also affect the access_EPI() itself unless it is already a library function.

    To eliminate everything else I will suggest a two pass approach. In pass 1, you do the code sequence listed above. In the second pass you will modify the above code like below, simply adding another access_EPI().

    x = SysTickValueGet();
    for (i=0;i<8;i++){
    access_EPI();
    access_EPI();
    }
    y = SysTickValueGet();
    time_difference = y-x;

    Now you will have the 'time_difference' recorded from both pass1 and pass2. Take the difference between these two 'time_difference' you will get the amount of time to execute the access_EPI() eight times. To get the amount of time in one access_EPI() you just divide by 8.

    There maybe other clever ways that other community members can share.
  • Charles Tsai said:
    There maybe other clever ways that other community members can share.

    While (avoiding) any claims/representations of "clever" - does not the "for loop" (w/in pass 2) insert an "avoidable" time burden (loop's execution time) into the measurement?

    Might the following improve the measurement?

    x = SysTickValueGet();

    access_EPI();
    access_EPI();
    access_EPI();
    access_EPI();
    access_EPI();
    access_EPI();
    access_EPI();
    access_EPI();

    y = SysTickValueGet();   //  this function adds to the overall execution time of this sequence

    time_difference = y-x;   // with an 8, 16 or 32 "back to back" EPI sequence - a simple "shift" (by 3, 4 or 5) - after the "y-x subtraction" - avoids the need to divide.

    If a unique EPI address bit can be toggled with the FINAL "access_EPI()" - that (may) be latched by a Timer - eliminating the time penalty introduced by SysTickValue Get().   That same Timer would be "Cleared & Enabled" by instruction - just prior to the "EPI barrage" - thus replacing the first (top) "SysTickValue Get()."   (i.e. Clear & Enable Timer first - Execute the sequence of EPIs - Halt upon the appearance of a unique EPI address bit.)   Again - we don't know or use 129x - yet I KNOW this method to work w/other ARM Cortex M4s & M7...

    As neither firm/I use 129x - I cannot know if so simple (and repeated) an "access" (i.e. possibly w/out address increment/decrement) provides/reflects, "real world" timings...  

    Let the record show that "Pro IDEs (IAR, Keil)" both provide "Automated Measurement & Display of such timings" - NO/ZERO Code Required!   (while being "vendor agnostic")

  • Hi cb1,
    Thanks for sharing your idea.

    Let me define as follows:

    a = time to execute one SysTickValueGet;
    b = time to execute the for-loop and the branch back
    c = time to execute one access_EPI()

    In pass 1, the total amount of time will be a + 8 * ( b + c) + a
    In pass 2, the total amount of time will be a + 8 * ( b + c + c) + a

    The difference between the two passes will be 8 * c. If you divide by 8 you get only the time for c which is the time to execute one access_EPI(). With this approach you can eliminate the overheads associated with the for-loop and the two SysTickValueGet(). I think the accuracy may get better if the number of iterations is increased, i.e. from 8 to 16 in the for-loop and later divide by 16 to get one access_EPI().
  • Thanks, I measured DATA[7]=ui32MAPPINGAD[0X000000] in your way,and i found it is 100ns,but is it normal?

    how long does read the SRAM time should take by EPI ?

    Another problem, I feel my 1294 did not run in 120MHz, because the gap between  the time of execution for one statement and the time  I calculate is too big, what reason is this?

  • Hi,

    What about measuring with a good oscilloscope, synchronized with EPI clock on one channel?

    This is the only tool to reveal the real duration.

    Also, some more info about your device, connected to EPI would be useful.

    The working waveforms are in the user manual, check also them.

    Replace the functions  in driverlib with the ROM_ versions.

  • I am so appreciate,b ut  I wanna if you can help me to cheek the wave I  measured 3 singnals;singnals1 is busy of ADC,singnal2 is the LED I light in the ADC read  handler.singnal3 is the LED I light in the Timer handler,I find the time between edge 1and2 is about 500ns,I set the interrupt risingedge ,but why it takes so long?

    and the high level time is 3.9us(yellow),900ns(blue),800ns(pink),and the code is bellow:

    void
    Timer0IntHandler(void)
    {
    ROM_TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);

    ROM_GPIOPinWrite(GPIO_PORTM_BASE, GPIO_PIN_6, GPIO_PIN_6);

    ROM_GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_4, 0); //CONVSTA=0
    ROM_GPIOPinWrite(GPIO_PORTD_BASE, GPIO_PIN_4, GPIO_PIN_4); //CONVSTA=1

    if(intflag==0)
    {
    GPIOIntRegister(GPIO_PORTF_BASE, ADReadIntHandler);
    ROM_GPIOIntTypeSet(GPIO_PORTF_BASE,GPIO_PIN_1,GPIO_RISING_EDGE);
    ROM_IntEnable(INT_GPIOF);
    ROM_GPIOIntEnable(GPIO_PORTF_BASE, GPIO_PIN_1);
    intflag=1;
    }
    ROM_IntMasterDisable();
    ROM_GPIOPinWrite(GPIO_PORTM_BASE, GPIO_PIN_6, 0);
    ROM_IntMasterEnable();
    }

    void ADReadIntHandler(void)
    {
    ROM_GPIOIntClear(GPIO_PORTF_BASE,GPIO_PIN_1);

    ROM_GPIOPinWrite(GPIO_PORTM_BASE, GPIO_PIN_5, GPIO_PIN_5);
    // SysCtlDelay(120000000 /100000000/ 3);
    DATA[0]=ui32MAPPINGAD[0X000000];
    DATA[1]=ui32MAPPINGAD[0X000000];
    DATA[2]=ui32MAPPINGAD[0X000000];
    DATA[3]=ui32MAPPINGAD[0X000000];
    DATA[4]=ui32MAPPINGAD[0X000000];
    DATA[5]=ui32MAPPINGAD[0X000000];
    DATA[6]=ui32MAPPINGAD[0X000000];
    DATA[7]=ui32MAPPINGAD[0X000000];
    g_pui8USBTxBuffer[0]=DATA[ADCChannel]&0XFF;
    g_pui8USBTxBuffer[1]=(DATA[ADCChannel]>>8)&0XFF;
    StatusReg=0x00FF;
    ROM_IntMasterDisable();
    ROM_IntMasterEnable();
    ROM_GPIOPinWrite(GPIO_PORTM_BASE, GPIO_PIN_5, 0);
    }

    I don't know why the time  is so long,and is it related to the setting?

  • Hi Wei,
    You seem to be asking a different question unrelated to the EPI, is this correct?
  • Hello Wei,

    A couple of thoughts here:

    - At 120MHz, each clock cycle on the processor takes 8.3ns - nothing we can do about it. A set of instructions that require 10 cycles would take 83ns, period.
    - Yes, again: optimization can change the time the "whole process" takes to happen - optimization will work mostly on the loops structure, variable placement (registers/memory), etc...
    - If you halt the processing and look at the assembly code for your ISR, you can somewhat "evaluate" the number of cycles. Then you can either look for ARM documentation to see how many cycles each instructions take, or use "more resourceful IDE's" as cb1 suggests.

    100ns is about 12 cycles, it ain't too much... Do you really need faster than that? In that case, maybe this is not the chip for you. Note that, if your interrupt event happens while you are servicing ANOTHER interrupt, you will still have to wait for that one to finish before you start servicing the new one - and thus things will take even longer.

    Finally, please use the </> button (inside "rich formatting") to post your code. It is really hard to read the code inside the forum messages if you just past with no formatting.

    Cheers

    Bruno
  • YES but now it seems that YOU and Cheers Bruno and cb1_mobile have already solved my problem. thank you so much!
  • Thank you it confused me so long time,but I will change it to register form and revise my code,and this is my first time put code on the blog so I did not notice that I did not use </>,but thank you very much!
  • I AM SORRY !I have another question:
    how long will it take read data for one time from exterior SRAM to internal RAM by using EPI?
  • Hi Wei,

      Sorry, I don't have this data. I think you can do this benchmark faster than me as I don't currently have a board with the EPI interfacing to an external SRAM. Remembered the method I suggested to measure the EPI. I believe you can use the same method with the 2 pass approach. You will read from the SRAM to an internal variable stored in the internal RAM. The difference between the 2 passes is the number of cycles taken to read 8 times of external SRAM to an internal variable. Divide by 8 you should get one iteration of reading from external SRAM to internal RAM. When you read from SRAM, the data has to travel from the EPI module and some interconnect (fabric which glues the system together) before loading into a CPU register. Then the data will need to be written from the register to the RAM. 

    // pass1
    SRAM_config(); // for illustration purpose to configure the EPI for SRAM access uint32 data; x = SysTickValueGet(); for (i=0;i<8;i++){ data = *(SRAM_location); } y = SysTickValueGet(); time_difference = y-x;
    / pass2
    SRAM_config(); // for illustration purpose to configure the EPI for SRAM access uint32 data; x = SysTickValueGet(); for (i=0;i<8;i++){ data = *(SRAM_location);
     data = *(SRAM_location); 
    } 
    y = SysTickValueGet();
    time_difference = y-x;

  • Sorry, the code pasted is a bit messed up. Hope you can still read it and understand what I meant.
  • Hi,

    The EPI is designed for accessing lower speed peripherals, including SRAM - so if you like to find out an answer to your question, tell us (from the data sheet) what is the access time of your device and how did you configured it - since you may add some wait states to have good behaviour of your device. Do not use the defaults, since they could not match your device.

    Also, take into account the SysTick interrupt could not provide useful data - depends on how it is configured, but in any case, it is not suitable in nano-microseconds ticks, the resolution is always a single SysTick, which may be wrong, and could stress your micro(too often interrupts..). For a more precise measurement, with a resolution of 1 clock cycle, see this link.

    Do not forget to use an oscilloscope.