LPC1549 Multirate Timer Configuration Issue

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

LPC1549 Multirate Timer Configuration Issue

1,080 Views
rajeshsh_
Contributor I

Dear All,

I am using LPC1549 Xpresso board for my initial development projects. Also, I am using LPCOpen libraries in KEIL MDK.

At present, I am using Multirate Timer (MRT) feature of this LPC1549 microcontroller as per datasheet UM10736, Chapter 19. For this, I am using LPCOpen libraries available for chip_15xx.

Purpose is to generate timer interrupt (Repeat Interupt Mode, Channel 0) @ 1 sec interval. For this, I did following coding :

#define DEF_CHANNEL 0

/* Set up and initialize clocking prior to call to main */

void MyBoardSetupIntClocking(void)

{

     volatile int i;

    /* Powerup main IRC (likely already powered up) */

   Chip_SYSCTL_PowerUp(SYSCTL_POWERDOWN_IRC_PD);

   Chip_SYSCTL_PowerUp(SYSCTL_POWERDOWN_IRCOUT_PD);

  /* Wait 200us for OSC to be stablized, no status indication, dummy wait. */

   for (i = 0; i < 0x500; i++) {}   

    /* Set system PLL input to IRC */

  Chip_Clock_SetSystemPLLSource(SYSCTL_PLLCLKSRC_IRC);

    /* Power down PLL to change the PLL divider ratio */

  Chip_SYSCTL_PowerDown(SYSCTL_POWERDOWN_SYSPLL_PD);

    /* Setup PLL for main oscillator rate (FCLKIN = 12MHz) * 6 = 72MHz MSEL = 5 (this is pre-decremented), PSEL = 1 (for P = 2)

   FCLKOUT = FCLKIN * (MSEL + 1) = 12MHz * 6 = 72MHz

   FCCO = FCLKOUT * 2 * P = 72MHz * 2 * 2 = 288MHz (within FCCO range)

*/

   LPC_SYSCTL->SYSPLLCTRL=0x00000045;

   /* Powerup system PLL */

   Chip_SYSCTL_PowerUp(SYSCTL_POWERDOWN_SYSPLL_PD);

   /* Wait for PLL to lock */

   while (!Chip_Clock_IsSystemPLLLocked()) {}

   /* Set system clock divider to 1 */

   Chip_Clock_SetSysClockDiv(1);

   /* Setup FLASH access timing for 72MHz */

   Chip_FMC_SetFLASHAccess(SYSCTL_FLASHTIM_72MHZ_CPU);

   /* Set main clock source to the system PLL. This will drive 72MHz for the main clock */

   Chip_Clock_SetMainClockSource(SYSCTL_MAINCLKSRC_SYSPLLOUT);

}

/**

* @brief    Handle interrupt from MRT

* @return    Nothing

*/

void MRT_IRQHandler(void)

{

    Chip_MRT_IntClear(Chip_MRT_GetRegPtr(DEF_CHANNEL));

    /*Clear the intrrupt pending flag*/

     if(Chip_MRT_GetIntPendingByChannel(DEF_CHANNEL))

     {

         /*Clear the pending intterupt*/

        Chip_MRT_IntPending(Chip_MRT_GetRegPtr(DEF_CHANNEL));

     }

//Blink LED

     Chip_GPIO_SetPinToggle(LPC_GPIO, led_port[1], led_pin[1]);

}

void initTimer(uint8_t channel, MRT_MODE_T mode, uint32_t rate)

{

    /* Enable the clock to the register interface */

    Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_MRT);

    /* Reset MRT */

    Chip_SYSCTL_PeriphReset(RESET_MRT);

    /*Get the channel pointer and disable that Timer*/

    Chip_MRT_SetDisabled(Chip_MRT_GetRegPtr(channel));

    /*Enable the Intterupt for the Timer*/

    NVIC_EnableIRQ(MRT_IRQn);;

    /*Setup the timer with requested rate */

    Chip_MRT_SetInterval(Chip_MRT_GetRegPtr(channel), (Chip_Clock_GetSystemClockRate() / rate) |  MRT_INTVAL_LOAD);

    /*Set the Timer mode*/

    Chip_MRT_SetMode(Chip_MRT_GetRegPtr(channel),mode);

    /*Clear the pending intterupt*/

    Chip_MRT_IntPending(Chip_MRT_GetRegPtr(channel));

    /*Enable the Timer correspond to the requested channel*/

    Chip_MRT_SetEnabled(Chip_MRT_GetRegPtr(channel));  

}

/**

* @brief    main routine for blinky example

*/

int main(void)

{

    MyBoardSetupIntClocking();

    SystemCoreClockUpdate();

    initTimer(DEF_CHANNEL,MRT_MODE_REPEAT,1);

    while(1)

    {  

        __WFI();

    }

    return 0;

}

My queries:

1. Some how, I think my clock frequency is not getting setup properly. I want to work with 72 MHz clock frequency, so at this frequency, I want to generate different timer delays.

2. No matter what clock frequency I set ( 72 MHz or 12 MHz or 24 MHz), Blink interval of the LED must remain same (i.e. 1 sec), according to this API call by passing parameter "rate":

Chip_MRT_SetInterval(Chip_MRT_GetRegPtr(channel), (Chip_Clock_GetSystemClockRate() / rate) |  MRT_INTVAL_LOAD);

The "rate" parameter is desired frequency.

The problem is whenever I am changing the clock frequency , the blink interval get changes.

3. My purpose is to generate delays and interrupts in millisecond and microsecond interval. Which timer is most suitable out of MRT, RIT(Repititive Interupt Timer), SysTick Timer ?

Regards,

Raj S.

Labels (3)
0 Kudos
1 Reply

543 Views
isaacavila
NXP Employee
NXP Employee

Hello Rajesh

Sorry for late response, according to your queries, here are the answers:

  • Why do you think that PLL is not being set correctly? Following is an initialization that I used for LPCXpresso1549 board and it worked well:
        /* Powerup main IRC (likely already powered up) */
     Chip_SYSCTL_PowerUp(SYSCTL_POWERDOWN_IRC_PD);
     Chip_SYSCTL_PowerUp(SYSCTL_POWERDOWN_IRCOUT_PD);

     /* Wait 200us for OSC to be stablized, no status
        indication, dummy wait. */
     for (i = 0; i < 0x200; i++) {}

     /* Set system PLL input to main oscillator */
     Chip_Clock_SetSystemPLLSource(SYSCTL_PLLCLKSRC_IRC);

     /* Power down PLL to change the PLL divider ratio */
     Chip_SYSCTL_PowerDown(SYSCTL_POWERDOWN_SYSPLL_PD);

     /* Setup PLL for main oscillator rate (FCLKIN = 12MHz) * 6 = 72MHz
        MSEL = 5 (this is pre-decremented), PSEL = 1 (for P = 2)
        FCLKOUT = FCLKIN * (MSEL + 1) = 12MHz * 6 = 72MHz
        FCCO = FCLKOUT * 2 * P = 72MHz * 2 * 2 = 288MHz (within FCCO range) */
     Chip_Clock_SetupSystemPLL(5, 2);

     /* Powerup system PLL */
     Chip_SYSCTL_PowerUp(SYSCTL_POWERDOWN_SYSPLL_PD);

     /* Wait for PLL to lock */
     while (!Chip_Clock_IsSystemPLLLocked()) {}

     /* Set system clock divider to 1 */
     Chip_Clock_SetSysClockDiv(1);

     /* Setup FLASH access timing for 72MHz */
     Chip_FMC_SetFLASHAccess(SYSCTL_FLASHTIM_72MHZ_CPU);

     /* Set main clock source to the system PLL. This will drive 72MHz
        for the main clock */
     Chip_Clock_SetMainClockSource(SYSCTL_MAINCLKSRC_SYSPLLOUT);
  • Are you sure that INTVAL register has a valid IVALUE? Remeber that MRT is a 24-bit timer, and, when you configure to get an interrupt every 1 seg, you configure IVALUE to be (72MHz / 1Hz = 72000000 or 0x44AA200), as you may see, 0x44AA200 cannot be set to MRT (it is a 28-bit value) so period for this timer is not the want that you desire:

MRT period.jpg

So, you cannot get a 1 Hz frequency when MRT uses 72 MHz as its source frequency.

  • Taking in mind this previous point, you can use RIT period which is a 48-bit counter that is fed from Main Clock. It can provide a bigger period timer than Systcik and MRT (24-bit counters)

I hope this helps!

Regards,

Isaac

0 Kudos