This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Strange problem with the VPBDIV register

Hi:
I tried the following code:


#include <LPC21XX.h>
#include <stdio.h>

#define OSC_CLOCK_FREQ 14745600
#define CR     0x0D

void
UARTInitialize(unsigned int baud)
{
  U0LCR = 0x83; /* 8 bit, 1 stop bit, no parity, enable DLAB */
  U0DLL = 192;	/* 9600 bps @ Peripheral Clock = 2 * 14745600 MHz */
  U0DLM = 0;
  U0LCR &= ~0x80; /* Disable DLAB */
  PINSEL0 = (PINSEL0 & ~0xF) | 0x5;
  U0FCR = 1;
}

unsigned int
cClkFreq(void)
{
  return (OSC_CLOCK_FREQ * (PLLCON & 1 ? (PLLCFG & 0x1F) + 1 : 1));
}

unsigned int
pClkFreq(void)
{
  unsigned int divider=0;
  switch (VPBDIV & 3)
    {
      case 0:
        divider = 4;
        break;
      case 1:
        divider = 1;
        break;
      case 2:
        divider = 2;
        break;
    }
  return cClkFreq() / divider;
}

int putchar(int ch)
{
  if (ch == '\n')  {
    while (!(U0LSR & 0x20));
    U0THR = CR;
  }
  while (!(U0LSR & 0x20));
  return (U0THR = ch);
}

int main (void) {
   UARTInitialize(9600);

   printf("Processsor Clock %d\n", cClkFreq());
   printf("Peripheral Clock %d\n", pClkFreq());
   printf("Peripheral Clock %d\n", pClkFreq());
   printf("Peripheral Clock %d\n", pClkFreq());

  while (1) ;
  return 0;
}

It is compiled with Keil CARM, and the VPB Clock = CPU Clock / 2
The first printf the peripheral clock prints a wrong value, while the rest are correct.
Apparently, the problem is when the VPBDIV register is read. The first time it reads as zero, while the rest it reads the correct value.

Someone have any idea about this?
Thanks
Daniel

  • Probably your problem relates to the following LPC2129 errata sheet topic:

    VPBDIV.1 Incorrect read of VPBDIV
    Introduction: The Peripheral Bus Divider (VPBDIV) divides the processor clock (CCLK) by one, two, or four. This
    is the clock that is provided to the peripheral bus.
    Problem: Reading the VPBDIV register may return an incorrect value.
    Work-around: Performing two consecutive reads of the VPBDIV assures that the correct value is returned.