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.

TMS570LS12 Software delays using gio pins

Other Parts Discussed in Thread: HALCOGEN

Hi team please refer to the below code, I was just trying to measure the software delays by toggling the gpio pin  using scope.

I have used HALCOGEN to generate code for GIO driver.

void main(void)

gioInit(); //initalize gio driver

gioSetDirection(gioPORTA, 0x000000FE);

gioSetBit(gioPORTA, 1, 1);


#if 0         //dummy code 

gioSetBit(gioPORTA, 2, 1);

if(gioGetBit(gioPORTA,2))
{
printf("bit is set");
}
else
{
printf("bit is not set");
}

gioSetBit(gioPORTA, 5, 0);

if(gioGetBit(gioPORTA,5))
{
printf("bit is set");
}
else
{
printf("bit is not set");
}

#endif


while(1)
{

gioSetBit(gioPORTA, 1, 0); // set pin 1 as low

delay(925); // delay

gioSetBit(gioPORTA, 1, 1); // set pin 1 as high

delay(10000); //delay

}

}
void delay(long value)
{
long i;

for(i=0;i<value;i++);

}

if I'm not including the dummy code  ( #if 0 )  and measure the delay for the off time  using the scope, I got 104 microseconds but once when I try to include this dummy code (by making #if 1) the delay i could measure for the off time is just 87 microseconds which is reduced. And if I add some more codes the delay is further getting reduced (without changing the delay value 925). I expect that the delay should not be changing even if i  add some more tasks but  eventually its not happening its keep on changing something I don't understand so could some one please suggest or help me regarding this.

Thanks in advance,

Regards,

Bala

  • Hi Bala,
    I'm looking into your problem. I will get back to you.
  • Hi Bala,
    Can you tell me if you are getting any abort? Please put a breakpoint on the below line in the sys_intvecs.asm file:

    b _dabort

    If you are getting abort then can you tell me what is the cause of the abort by looking at the CPU Data Fault Status Register.
  • Hi Bala,
    I did some experiments. I was able to confirm that the code before the while(1) can affect the length of the delay(). After some investigation I found that it has to do with the combination of the pipeline architecture of the flash and the placement of the delay() function. If I disable the flash pipeline mode then I see the same low phase width of the GIO whether I have #if 0 or #if 1.

    The flash controller has the pipeline mode enabled by default. The way it works is to prefetch the next several sequential instructions (up to 4 32-bit instructions) from the flash bank in advance and store them in a local buffer anticipating that the CPU will ultimately read them. So if the CPU does read them then it is a pipeline hit which only consumes 1 CPU cycle. If it is a pipeline miss, then the flash controller will need to read from the flash bank. This can take several cycles to complete.

    When you add some instructions before the delay() it can affect where the delay() can be placed in your program. This can slightly affect the total amount of cycles to execute the delay() for one loop when it is delay(1). If it is delay(925) then it certainly multiple. Note that adding instructions before the delay() can either reduce or increase the number of cycles. It will depend where the delay() starts relative to the 128-bit boundary.

    Try to disable the pipeline mode by setting the bit 0 of the flash control register to 0 and you should see consistent result.

    flashWREG->FRDCNTL = 0x00000000U
    | (uint32)((uint32)3U << 8U)
    | (uint32)((uint32)1U << 4U)
    | 0U;

    A software timer is never an accurate way to produce a fixed delay. The compiler optimization, number of wait states corresponding to the operating frequency and the pipeline mode can all play a role to affect the delay.
  • Hi Charles,

    Thanks for the effort and support.

    Coming to the problem, now I could measure  constant delay irrespective of code I add before the delay() function. Further I would like know will this normal mode of flash operating will affect my code anyways in future or could you little more explain what is actually done in Pipeline mode and normal mode of flash operations ? 

    Regards,

    Bala

  • Hi Bala,
    For your normal operation you definitely want to enable the pipeline mode to maximize the processor performance. As I mentioned in pipeline mode the flash controller will prefetch the next sequential instructions in advance and store them in a local buffer temporarily so that when the CPU reads them later it is readily available in a very fast turn around. Let me give you an example.

    It takes some time to read the flash. The flash can be accessed in one single cycle at about 50MHz. So if you operate the CPU at 50MHz, every read from the CPU takes one CPU cycle to complete. However, you are not operating at 50MHz but rather like 180MHz. So you need several wait states to access the flash. During the wait states, the CPU is idle waiting. The pipeline architecture is a feature inside the flash controller where it will prefetch some instructions in advance hoping that the CPU will read them eventually. When the CPU does read the instructions that the pipeline logic predicts the CPU will read then the instructions is available to the CPU in 1 cycle rather than multiple wait states. However, when you take a branch, it is not sequential code anymore, the pipeline logic thus needs to flush its pipeline and refetch the requested instruction while the CPU is waiting.

    So you want to enable pipeline. As far as the software delay, it will not be accurate. For the PWM you are trying to generate you should use the hardware based NHET timer on the device. It can generate the precise period and duty cycle for you.
  • Hi Charles,

    Thanks for the support.

    As you suggested I will try to use the Hardware based NHET timer.

    Regards
    Bala.
  • Hi Bala,
    Glad your problem is resolved. On LS12x device there are both the NHET and ePWM modules. You can use either one to create PWM waveform.