lpcware

LPC1769 Timer0 mystery when running from RAM

Discussion created by lpcware Employee on Jun 15, 2016
Content originally posted in LPCWare by user1769 on Wed May 08 10:34:49 MST 2013
On a LPCXpresso 1769 board, running at 120 MHz, I have setup timer0 to generate a interrupt at 1kHz, with this code:

//-----------------------------------------------------------------------------
void IO_Init(void)
{
  LPC_SC->PCONP |= (1 << 15);                        // enable power to GPIO & IOCON
  LPC_SC->PCLKSEL1 &= ~(3 << 2);                // GPIO interrupts = clk/4 = 30MHz

  LPC_SC->PCONP |= (1 << 1);                     // power up timer0
  LPC_SC->PCLKSEL0 &= ~(3 << 2);                // clock for timer0 = CCLK/4 = 30MHz
  LPC_SC->PCLKSEL0 |=  (2 << 2);                // clock for timer0 = CCLK/2 = 60MHz

  LPC_TIM0->TCR = 2;                                // reset & hold timer
  LPC_TIM0->MR0 = 60000-1;                    // timer0 irq @ 1kHz
  LPC_TIM0->MCR |= 1 << 0;                     // interrupt on Match0 compare
  LPC_TIM0->MCR |= 1 << 1;                     // reset timer on Match 0
  NVIC_SetPriority(TIMER0_IRQn, PRIORITY_TIMER0);
  NVIC_EnableIRQ(TIMER0_IRQn);                     // enable timer0 interrupt
  LPC_TIM0->TCR = 1;                         // stop resetting the timer, start timer

  LPC_GPIO0->FIODIR |= (1 << 22);                 // LED P0.22 output mode
}

//-----------------------------------------------------------------------------
void TIMER0_IRQHandler(void)                    // @1ms
{
  if ((LPC_TIM0->IR & 1) == 1) {                // if MR0 interrupt
    LPC_TIM0->IR |= 1;                         // Clear MR0 interrupt flag
    LPC_GPIO0->FIOPIN ^= 1 << 22;                 // Toggle the LED
  }
}

In Flash, this works, I can see the resulting 500Hz square wave at pin 0.22.

Then I compile this for debugging / running in RAM, Keil IDE, for this the script Dbg_RAM.ini is used, which comes with Keil IDE:

/*----------------------------------------------------------------------------
* Name:    Dbg_RAM.ini
* Purpose: RAM Debug Initialization File
* Note(s):
*----------------------------------------------------------------------------
* This file is part of the uVision/ARM development tools.
* This software may only be used under the terms of a valid, current,
* end user licence from KEIL for a compatible version of KEIL software
* development tools. Nothing else gives you the right to use this software.
*
* This software is supplied "AS IS" without warranties of any kind.
*
* Copyright (c) 2008-2011 Keil - An ARM Company. All rights reserved.
*----------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------
  Setup()  configure PC & SP for RAM Debug
*----------------------------------------------------------------------------*/
FUNC void Setup (void) {
  SP = _RDWORD(0x10000000);                          // Setup Stack Pointer
  PC = _RDWORD(0x10000004);                          // Setup Program Counter
  _WDWORD(0xE000ED08, 0x10000000);                   // Setup Vector Table Offset Register
  _WDWORD(0x400FC0C4, _RDWORD(0x400FC0C4) | 1<<12);  // Enable ADC Power
  _WDWORD(0x40034034, 0x00000F00);                   // Setup ADC Trim
}

LOAD %L INCREMENTAL                                  // load the application

Setup();                                             // Setup for Running

g, main


Now, I can see that the interrupt is called only at 500 Hz, resulting in a 250Hz square wave at pin 0.22.

What am I missing here with timer0? Maybe someone can explain that unexpected behaviour.

Thank you very much,
Tom

Outcomes