lpcware

Code alignment interfering on instruction temporization. Is it a Bug of the chip or is it normal?

Discussion created by lpcware Employee on Jun 15, 2016
Latest reply on Jun 15, 2016 by lpcware
Content originally posted in LPCWare by Danjovic on Sat Jul 27 16:33:10 MST 2013
Hi

I am writing a video generating routine for the LPC1111/201 based on the Systick interrupt for generating the Hsync timing.

For pulse temporization I am writing a delay loop in assembly, so I can have a predictable temporization.

But I have noticed a strange behavior of the chip regarding the changing in execution timing of the delay loops that is related to the lenght of code generated. Is it normal? Let me explain better:

This is the structure of my code. For simplicity I have shown only the HSYNC routine but I have another two routines for generating VSYNC and Horizontal Equalization pulses.

main () {
  SystemInit();
  LPC_IOCON->PIO0_7 = (0x0) + (0<<3) + (0<<5);
  LPC_GPIO0->MASKED_ACCESS[1<<7] = 0;
  LPC_GPIO0->DIR = LPC_GPIO0->DIR | (1<<7);
  SysTick_Config(H_LINE_TICKS); // number of ticks to interrupt at 63,5us
  for (;;);
}

void SysTick_Handler(void)
{
H_Sync();
}

__inline void H_Sync(void)
{
// H_sync pulse 4.7us
LPC_GPIO0->DATA &= ~(1<<7);
asm("push {r1}\n\t"
"mov r1, #22\n\t"
"Loophs1:\n\t"
"subr1, r1, #1\n\t"
"cmpr1, #0\n\t"
"bneLoophs1\n\t"
"pop {r1}\n\t"
);
    LPC_GPIO0->DATA |= (1<<7);
}

The code above generates a Hsync pulse with a duration of 4.7us at each SysTick Interrupt.

Well, the problem began to show when I have added code for changing a second pin at the beginning of code in 'main()'.

main () {
  SystemInit();
  LPC_IOCON->PIO0_7 = (0x0) + (0<<3) + (0<<5);
  LPC_GPIO0->MASKED_ACCESS[1<<7] = 0;
  LPC_GPIO0->DIR = LPC_GPIO0->DIR | (1<<7);

  LPC_IOCON->PIO0_9 = (0x0) + (0<<3) + (0<<5);
  LPC_GPIO0->MASKED_ACCESS[1<<9] = 0;
  LPC_GPIO0->DIR = LPC_GPIO0->DIR | (1<<9);


  SysTick_Config(H_LINE_TICKS); // number of ticks to interrupt at 63,5us
  for (;;);
}



when I did that, the pulse width changed from 4.7us to 2.8us!!! After some time investigating I have found that if I put a pair or NOPS for stuffing the main, the delay loops became normal again.


main () {
  SystemInit();
  LPC_IOCON->PIO0_7 = (0x0) + (0<<3) + (0<<5);
  LPC_GPIO0->MASKED_ACCESS[1<<7] = 0;
  LPC_GPIO0->DIR = LPC_GPIO0->DIR | (1<<7);

  LPC_IOCON->PIO0_9 = (0x0) + (0<<3) + (0<<5);
  LPC_GPIO0->MASKED_ACCESS[1<<9] = 0;
  LPC_GPIO0->DIR = LPC_GPIO0->DIR | (1<<9);

  asm("nop");
  asm("nop");


  SysTick_Config(H_LINE_TICKS); // number of ticks to interrupt at 63,5us
  for (;;);
}


If I put only 1 'NOP' the timing stills wrong.
If I put 2 to 5 'NOPS' the timing is correct.
If I put 6 to 9 'NOPS' the timing is again wrong
if I put 10 'NOPs' the timing is again correct.

Do anybody went into a situation like that? What can be causing this behavior? Is it normal for the LPC1111 or other Cortex M0 chips?Is there any way to aovid this to happen, maybe a configuration option?

I think it is worth to mention that the Systick operation is normal (do not present any changing due to NOPS).

Outcomes