<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>LPC MicrocontrollersのトピックRe: Multiple channels of Multi-Rate Timer (MRT) on LPC55S28</title>
    <link>https://community.nxp.com/t5/LPC-Microcontrollers/Multiple-channels-of-Multi-Rate-Timer-MRT-on-LPC55S28/m-p/1288250#M45327</link>
    <description>&lt;P&gt;More debugging results. I removed all the code related to channels 2 and 3, and continued testing with only channels 0 and 1 to simplify things.&lt;/P&gt;&lt;P&gt;I set the following periods:&lt;/P&gt;&lt;LI-CODE lang="c"&gt;static const uint32_t CH0_INTERVAL_MS       = 10U;
static const uint32_t CH1_INTERVAL_MS       = 1000U;&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;And removed PRINTF overhead from super loop:&lt;/P&gt;&lt;LI-CODE lang="c"&gt;    while (true)
    {
        /* Check whether interrupt occurred and toggle LED */
        if (true == mrtIsrFlag0)
        {          
            if (count0 == 6000U)    // 60 sec == 10 msec * 6000 
            {
                PRINTF("\r\n [0] %u", count0 * CH0_INTERVAL_MS);
                PRINTF("\r\n [1] %u", count1 * CH1_INTERVAL_MS);
                for(;;);
            }

            mrtCountValue0 = 0;
            mrtIsrFlag0    = false;
        }
        if (true == mrtIsrFlag1)
        {
            if (count1 == 60U)     // 60 sec == 1000 msec * 60
            {
                PRINTF("\r\n [1] %u", count1 * CH1_INTERVAL_MS);
                PRINTF("\r\n [0] %u", count0 * CH0_INTERVAL_MS);
                for(;;);
            }

            mrtCountValue1 = 0;
            mrtIsrFlag1    = false;
        }
    }&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I used stopwatch to see how long it takes for either if statement to execute. After little less than &lt;STRONG&gt;10 seconds&lt;/STRONG&gt; the "60 seconds" limit of channel 1 was reached:&lt;/P&gt;&lt;BLOCKQUOTE&gt;&lt;P&gt;Starting channel No.0 ...&lt;BR /&gt;Starting channel No.1 ...&lt;BR /&gt;mrtDividerValue0 = 0 (10 msec)&lt;BR /&gt;mrtDividerValue1 = 4 (1000 msec)&lt;BR /&gt;[1] 60000&lt;BR /&gt;[0] 9600&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;P&gt;Then I commented out that if statement to verify how long it takes for channel 0 to reach its limit:&lt;/P&gt;&lt;LI-CODE lang="c"&gt;    while (true)
    {
        /* Check whether interrupt occurred and toggle LED */
        if (true == mrtIsrFlag0)
        {          
            if (count0 == 6000U)    // 60 sec == 10 msec * 6000 
            {
                PRINTF("\r\n [0] %u", count0 * CH0_INTERVAL_MS);
                PRINTF("\r\n [1] %u", count1 * CH1_INTERVAL_MS);
                for(;;);
            }

            mrtCountValue0 = 0;
            mrtIsrFlag0    = false;
        }
        if (true == mrtIsrFlag1)
        {
//            if (count1 == 60U)     // 60 sec == 1000 msec * 60
//            {
//                PRINTF("\r\n [1] %u", count1 * CH1_INTERVAL_MS);
//                PRINTF("\r\n [0] %u", count0 * CH0_INTERVAL_MS);
//                for(;;);
//            }

            mrtCountValue1 = 0;
            mrtIsrFlag1    = false;
        }
    }&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;And it took exactly &lt;STRONG&gt;60 seconds&lt;/STRONG&gt;:&lt;/P&gt;&lt;BLOCKQUOTE&gt;&lt;P&gt;Starting channel No.0 ...&lt;BR /&gt;Starting channel No.1 ...&lt;BR /&gt;mrtDividerValue0 = 0 (10 msec)&lt;BR /&gt;mrtDividerValue1 = 4 (1000 msec)&lt;BR /&gt;[0] 60000&lt;BR /&gt;[1] 375000&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;P&gt;So channel 0 works alright, but the counter of channel 1 is updated 625% (375/60) more often than it should.&lt;/P&gt;&lt;P&gt;Then I noticed that I had completely forgot to do the same initializations for other channels than channel 0. I fixed that by:&lt;/P&gt;&lt;LI-CODE lang="c"&gt;    MRT_SetupChannelMode(MRT0, kMRT_Channel_0, kMRT_RepeatMode);
    MRT_SetupChannelMode(MRT0, kMRT_Channel_1, kMRT_RepeatMode);  // this was missing

    MRT_EnableInterrupts(MRT0, kMRT_Channel_0, kMRT_TimerInterruptEnable);
    MRT_EnableInterrupts(MRT0, kMRT_Channel_1, kMRT_TimerInterruptEnable);  // so was this&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Now I was quite confident that it would finally work. But after around &lt;STRONG&gt;~52 seconds&lt;/STRONG&gt; I got the same result:&lt;/P&gt;&lt;BLOCKQUOTE&gt;&lt;P&gt;Starting channel No.0 ...&lt;BR /&gt;Starting channel No.1 ...&lt;BR /&gt;mrtDividerValue0 = 0 (10 msec)&lt;BR /&gt;mrtDividerValue1 = 4 (1000 msec)&lt;BR /&gt;[0] 60000&lt;BR /&gt;[1] 375000&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;P&gt;I'm confused. How should this work?&lt;/P&gt;</description>
    <pubDate>Mon, 07 Jun 2021 11:18:25 GMT</pubDate>
    <dc:creator>vanska</dc:creator>
    <dc:date>2021-06-07T11:18:25Z</dc:date>
    <item>
      <title>Multiple channels of Multi-Rate Timer (MRT) on LPC55S28</title>
      <link>https://community.nxp.com/t5/LPC-Microcontrollers/Multiple-channels-of-Multi-Rate-Timer-MRT-on-LPC55S28/m-p/1287045#M45272</link>
      <description>&lt;P&gt;Hi,&lt;/P&gt;&lt;P&gt;I have some trouble understanding the limitations of using multiple channels of MRT at the same time. I took the LPCOpen example of MRT to demonstrate the problem and extended it to use all 4 channels instead of only one.&lt;/P&gt;&lt;P&gt;Code:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;LI-CODE lang="c"&gt;#include "fsl_debug_console.h"
#include "pin_mux.h"
#include "board.h"
#include "fsl_mrt.h"

#include &amp;lt;stdbool.h&amp;gt;
#include "fsl_power.h"
/*******************************************************************************
 * Definitions
 ******************************************************************************/
#define APP_LED_INIT   LED_RED_INIT(LOGIC_LED_OFF);
#define APP_LED_ON     (LED_RED_ON());
#define APP_LED_TOGGLE (LED_RED_TOGGLE());
#define MRT_CLK_FREQ   CLOCK_GetFreq(kCLOCK_BusClk)

/*******************************************************************************
 * Prototypes
 ******************************************************************************/

/*******************************************************************************
 * Variables
 ******************************************************************************/

static volatile bool mrtIsrFlag0            = false;
static volatile bool mrtEnableCount0        = false;
static volatile uint32_t mrtCountValue0     = 0;
static volatile uint32_t mrtDividerValue0   = 0;
static volatile uint32_t count0             = 0;
static const uint32_t CH0_INTERVAL_MS       = 200U;

static volatile bool mrtIsrFlag1            = false;
static volatile bool mrtEnableCount1        = false;
static volatile uint32_t mrtCountValue1     = 0;
static volatile uint32_t mrtDividerValue1   = 0;
static volatile uint32_t count1             = 0;
static const uint32_t CH1_INTERVAL_MS       = 250U;

static volatile bool mrtIsrFlag2            = false;
static volatile bool mrtEnableCount2        = false;
static volatile uint32_t mrtCountValue2     = 0;
static volatile uint32_t mrtDividerValue2   = 0;
static volatile uint32_t count2             = 0;
static const uint32_t CH2_INTERVAL_MS       = 500U;

static volatile bool mrtIsrFlag3            = false;
static volatile bool mrtEnableCount3        = false;
static volatile uint32_t mrtCountValue3     = 0;
static volatile uint32_t mrtDividerValue3   = 0;
static volatile uint32_t count3             = 0;
static const uint32_t CH3_INTERVAL_MS       = 1000U;

/*******************************************************************************
 * Code
 ******************************************************************************/
void MRT0_IRQHandler(void)
{
    if (MRT_GetStatusFlags(MRT0, kMRT_Channel_0))   // tried also "== 0x3" but same result
    {
        /* Clear interrupt flag.*/
        MRT_ClearStatusFlags(MRT0, kMRT_Channel_0, kMRT_TimerInterruptFlag);
        if (mrtEnableCount0 == true)
        {
            mrtCountValue0++;
            if (mrtCountValue0 == (1 &amp;lt;&amp;lt; mrtDividerValue0))
            {
                mrtIsrFlag0 = true;
                count0++;
            }
        }
        else
        {
            mrtIsrFlag0 = true;
            count0++;
        }
    }

    if (MRT_GetStatusFlags(MRT0, kMRT_Channel_1))   // tried also "== 0x3" but same result
    {
        /* Clear interrupt flag.*/
        MRT_ClearStatusFlags(MRT0, kMRT_Channel_1, kMRT_TimerInterruptFlag);
        if (mrtEnableCount1 == true)
        {
            mrtCountValue1++;
            if (mrtCountValue1 == (1 &amp;lt;&amp;lt; mrtDividerValue1))
            {
                mrtIsrFlag1 = true;
                count1++;
            }
        }
        else
        {
            mrtIsrFlag1 = true;
            count1++;
        }
    }

    if (MRT_GetStatusFlags(MRT0, kMRT_Channel_2))    // tried also "== 0x3" but same result
    {
        /* Clear interrupt flag.*/
        MRT_ClearStatusFlags(MRT0, kMRT_Channel_2, kMRT_TimerInterruptFlag);
        if (mrtEnableCount2 == true)
        {
            mrtCountValue2++;
            if (mrtCountValue2 == (1 &amp;lt;&amp;lt; mrtDividerValue2))
            {
                mrtIsrFlag2 = true;
                count2++;
            }
        }
        else
        {
            mrtIsrFlag2 = true;
            count2++;
        }
    }

    if (MRT_GetStatusFlags(MRT0, kMRT_Channel_3))   // tried also "== 0x3" but same result
    {
        /* Clear interrupt flag.*/
        MRT_ClearStatusFlags(MRT0, kMRT_Channel_3, kMRT_TimerInterruptFlag);
        if (mrtEnableCount3 == true)
        {
            mrtCountValue3++;
            if (mrtCountValue3 == (1 &amp;lt;&amp;lt; mrtDividerValue3))
            {
                mrtIsrFlag3 = true;
                count3++;
            }
        }
        else
        {
            mrtIsrFlag3 = true;
            count3++;
        }
    }

    SDK_ISR_EXIT_BARRIER;
}

/*!
 * @brief Main function
 */
int main(void)
{
    uint32_t mrt_clock;

    /* Structure of initialize MRT */
    mrt_config_t mrtConfig;

    /* Board pin, clock, debug console init */
    /* set BOD VBAT level to 1.65V */
    POWER_SetBodVbatLevel(kPOWER_BodVbatLevel1650mv, kPOWER_BodHystLevel50mv, false);
    /* enable clock for GPIO; used to toggle the LED's */
    CLOCK_EnableClock(kCLOCK_Gpio1);
    /* attach 12 MHz clock to FLEXCOMM0 (debug console) */
    CLOCK_AttachClk(BOARD_DEBUG_UART_CLK_ATTACH);

    BOARD_InitPins();
    BOARD_BootClockPLL150M();
    BOARD_InitDebugConsole();

    /* Initialize and enable LED */
    APP_LED_INIT;

    mrt_clock = MRT_CLK_FREQ;

    /* mrtConfig.enableMultiTask = false; */
    MRT_GetDefaultConfig(&amp;amp;mrtConfig);

    /* Init mrt module */
    MRT_Init(MRT0, &amp;amp;mrtConfig);

    /* Setup Channel 0 to be repeated */
    MRT_SetupChannelMode(MRT0, kMRT_Channel_0, kMRT_RepeatMode);

    /* Enable timer interrupts for channel 0 */
    MRT_EnableInterrupts(MRT0, kMRT_Channel_0, kMRT_TimerInterruptEnable);

    /* Enable at the NVIC */
    EnableIRQ(MRT0_IRQn);

    /* Start channel 0 */
    PRINTF("\r\nStarting channel No.0 ...");
    if (MSEC_TO_COUNT(CH0_INTERVAL_MS, mrt_clock) &amp;gt; MRT_CHANNEL_INTVAL_IVALUE_MASK)
    {
        mrtDividerValue0 = 0;
        mrtEnableCount0  = true;
        while (MSEC_TO_COUNT((CH0_INTERVAL_MS &amp;gt;&amp;gt; (++mrtDividerValue0)), mrt_clock) &amp;gt; MRT_CHANNEL_INTVAL_IVALUE_MASK)
        {
        }
        MRT_StartTimer(MRT0, kMRT_Channel_0, MSEC_TO_COUNT((CH0_INTERVAL_MS &amp;gt;&amp;gt; mrtDividerValue0), mrt_clock));
    }
    else
    {
        MRT_StartTimer(MRT0, kMRT_Channel_0, MSEC_TO_COUNT(CH0_INTERVAL_MS, mrt_clock));
    }

    PRINTF("\r\nStarting channel No.1 ...");
    if (MSEC_TO_COUNT(CH1_INTERVAL_MS, mrt_clock) &amp;gt; MRT_CHANNEL_INTVAL_IVALUE_MASK)
    {
        mrtDividerValue1 = 0;
        mrtEnableCount1  = true;
        while (MSEC_TO_COUNT((CH1_INTERVAL_MS &amp;gt;&amp;gt; (++mrtDividerValue1)), mrt_clock) &amp;gt; MRT_CHANNEL_INTVAL_IVALUE_MASK)
        {
        }
        MRT_StartTimer(MRT0, kMRT_Channel_1, MSEC_TO_COUNT((CH1_INTERVAL_MS &amp;gt;&amp;gt; mrtDividerValue1), mrt_clock));
    }
    else
    {
        MRT_StartTimer(MRT0, kMRT_Channel_1, MSEC_TO_COUNT(CH1_INTERVAL_MS, mrt_clock));
    }

    PRINTF("\r\nStarting channel No.2 ...");
    if (MSEC_TO_COUNT(CH2_INTERVAL_MS, mrt_clock) &amp;gt; MRT_CHANNEL_INTVAL_IVALUE_MASK)
    {
        mrtDividerValue2 = 0;
        mrtEnableCount2  = true;
        while (MSEC_TO_COUNT((CH2_INTERVAL_MS &amp;gt;&amp;gt; (++mrtDividerValue2)), mrt_clock) &amp;gt; MRT_CHANNEL_INTVAL_IVALUE_MASK)
        {
        }
        MRT_StartTimer(MRT0, kMRT_Channel_2, MSEC_TO_COUNT((CH2_INTERVAL_MS &amp;gt;&amp;gt; mrtDividerValue2), mrt_clock));
    }
    else
    {
        MRT_StartTimer(MRT0, kMRT_Channel_2, MSEC_TO_COUNT(CH2_INTERVAL_MS, mrt_clock));
    }

    PRINTF("\r\nStarting channel No.3 ...");
    if (MSEC_TO_COUNT(CH3_INTERVAL_MS, mrt_clock) &amp;gt; MRT_CHANNEL_INTVAL_IVALUE_MASK)
    {
        mrtDividerValue3 = 0;
        mrtEnableCount3  = true;
        while (MSEC_TO_COUNT((CH3_INTERVAL_MS &amp;gt;&amp;gt; (++mrtDividerValue3)), mrt_clock) &amp;gt; MRT_CHANNEL_INTVAL_IVALUE_MASK)
        {
        }
        MRT_StartTimer(MRT0, kMRT_Channel_3, MSEC_TO_COUNT((CH3_INTERVAL_MS &amp;gt;&amp;gt; mrtDividerValue3), mrt_clock));
    }
    else
    {
        MRT_StartTimer(MRT0, kMRT_Channel_3, MSEC_TO_COUNT(CH3_INTERVAL_MS, mrt_clock));
    }

    PRINTF("\r\nmrtDividerValue0 = %u (%u msec)", mrtDividerValue0, CH0_INTERVAL_MS);
    PRINTF("\r\nmrtDividerValue1 = %u (%u msec)", mrtDividerValue1, CH1_INTERVAL_MS);
    PRINTF("\r\nmrtDividerValue2 = %u (%u msec)", mrtDividerValue2, CH2_INTERVAL_MS);
    PRINTF("\r\nmrtDividerValue3 = %u (%u msec)", mrtDividerValue3, CH3_INTERVAL_MS);

    while (true)
    {
        /* Check whether interrupt occurred and toggle LED */
        if (true == mrtIsrFlag0)
        {
            PRINTF("\r\n [0] %u", count0 * CH0_INTERVAL_MS);
            APP_LED_TOGGLE;
            mrtCountValue0 = 0;
            mrtIsrFlag0    = false;
        }
        if (true == mrtIsrFlag1)
        {
            PRINTF("\r\n [1] %u", count1 * CH1_INTERVAL_MS);
            mrtCountValue1 = 0;
            mrtIsrFlag1    = false;
        }
        if (true == mrtIsrFlag2)
        {
            PRINTF("\r\n [2] %u", count2 * CH2_INTERVAL_MS);
            mrtCountValue2 = 0;
            mrtIsrFlag2    = false;
        }
        if (true == mrtIsrFlag3)
        {
            PRINTF("\r\n [3] %u", count3 * CH3_INTERVAL_MS);
            mrtCountValue3 = 0;
            mrtIsrFlag3    = false;
        }
    }
}&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;This is what gets printed on terminal:&lt;/P&gt;&lt;BLOCKQUOTE&gt;&lt;P&gt;Starting channel No.0 ...&lt;BR /&gt;Starting channel No.1 ...&lt;BR /&gt;Starting channel No.2 ...&lt;BR /&gt;Starting channel No.3 ...&lt;BR /&gt;mrtDividerValue0 = 1 (200 msec)&lt;BR /&gt;mrtDividerValue1 = 2 (250 msec)&lt;BR /&gt;mrtDividerValue2 = 3 (500 msec)&lt;BR /&gt;mrtDividerValue3 = 4 (1000 msec)&lt;BR /&gt;[0] 200&lt;BR /&gt;[1] 250&lt;BR /&gt;[0] 400&lt;BR /&gt;[0] 600&lt;BR /&gt;[2] 500&lt;BR /&gt;[0] 800&lt;BR /&gt;[1] 500&lt;BR /&gt;[0] 1000&lt;BR /&gt;[1] 750&lt;BR /&gt;[0] 1200&lt;BR /&gt;[0] 1400&lt;BR /&gt;[0] 1600&lt;BR /&gt;[1] 1000&lt;BR /&gt;[2] 1000&lt;BR /&gt;[3] 1000&lt;BR /&gt;[0] 1800&lt;BR /&gt;[0] 2000&lt;BR /&gt;[1] 1250&lt;BR /&gt;[0] 2200&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;P&gt;After 60 seconds I would expect msec counters to show roughly the same values (~60,000 msec).&lt;/P&gt;&lt;P&gt;Instead:&lt;/P&gt;&lt;BLOCKQUOTE&gt;&lt;P&gt;[2] 36000&lt;BR /&gt;[3] 36000&lt;BR /&gt;[0] 57800&lt;BR /&gt;[0] 58000&lt;BR /&gt;[1] 36250&lt;BR /&gt;[0] 58200&lt;BR /&gt;[0] 58400&lt;BR /&gt;[1] 36500&lt;BR /&gt;[2] 36500&lt;BR /&gt;[0] 58600&lt;BR /&gt;[0] 58800&lt;BR /&gt;[1] 36750&lt;BR /&gt;[0] 59000&lt;BR /&gt;[2] 37000&lt;BR /&gt;[3] 37000&lt;BR /&gt;[0] 59200&lt;BR /&gt;[1] 37000&lt;BR /&gt;[0] 59400&lt;BR /&gt;[0] 59600&lt;BR /&gt;[1] 37250&lt;BR /&gt;[0] 59800&lt;BR /&gt;[0] 60000&lt;BR /&gt;[1] 37500&lt;BR /&gt;[2] 37500&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;P&gt;Summary:&lt;/P&gt;&lt;P&gt;Channel 0: OK&lt;BR /&gt;Channel 1: NOK&lt;BR /&gt;Channel 2: NOK&lt;BR /&gt;Channel 3: NOK&lt;/P&gt;&lt;P&gt;Then I tried to simply swap the intervals in reverse order. Terminal:&lt;/P&gt;&lt;BLOCKQUOTE&gt;&lt;P&gt;Starting channel No.0 ...&lt;BR /&gt;Starting channel No.1 ...&lt;BR /&gt;Starting channel No.2 ...&lt;BR /&gt;Starting channel No.3 ...&lt;BR /&gt;mrtDividerValue0 = 4 (1000 msec)&lt;BR /&gt;mrtDividerValue1 = 3 (500 msec)&lt;BR /&gt;mrtDividerValue2 = 2 (250 msec)&lt;BR /&gt;mrtDividerValue3 = 1 (200 msec)&lt;BR /&gt;[3] 200&lt;BR /&gt;[2] 250&lt;BR /&gt;[3] 400&lt;BR /&gt;[3] 600&lt;BR /&gt;[3] 800&lt;BR /&gt;[1] 500&lt;BR /&gt;[2] 500&lt;BR /&gt;[3] 1000&lt;BR /&gt;[2] 750&lt;BR /&gt;[3] 1200&lt;BR /&gt;[3] 1400&lt;BR /&gt;[0] 1000&lt;BR /&gt;[1] 1000&lt;BR /&gt;[2] 1000&lt;BR /&gt;[3] 1600&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;P&gt;After 60 seconds:&lt;/P&gt;&lt;BLOCKQUOTE&gt;&lt;P&gt;[1] 59000&lt;BR /&gt;[2] 59000&lt;BR /&gt;[3] 94600&lt;BR /&gt;[2] 59250&lt;BR /&gt;[3] 94800&lt;BR /&gt;[3] 95000&lt;BR /&gt;[1] 59500&lt;BR /&gt;[2] 59500&lt;BR /&gt;[3] 95200&lt;BR /&gt;[3] 95400&lt;BR /&gt;[2] 59750&lt;BR /&gt;[3] 95600&lt;BR /&gt;[3] 95800&lt;BR /&gt;[0] 60000&lt;BR /&gt;[1] 60000&lt;BR /&gt;[2] 60000&lt;BR /&gt;[3] 96000&lt;BR /&gt;[3] 96200&lt;BR /&gt;[2] 60250&lt;BR /&gt;[3] 96400&lt;BR /&gt;[3] 96600&lt;BR /&gt;[3] 96800&lt;BR /&gt;[1] 60500&lt;BR /&gt;[2] 60500&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;P&gt;Summary:&lt;/P&gt;&lt;P&gt;Channel 0: OK&lt;BR /&gt;Channel 1: OK&lt;BR /&gt;Channel 2: OK&lt;BR /&gt;Channel 3: NOK&lt;/P&gt;&lt;P&gt;I don't remember seeing this on LPC1768 but maybe I was just lucky. Do I have some silly bug or is this expected behavior with this configuration? And most importantly, is there something that I could do to make this example work?&lt;/P&gt;&lt;P&gt;Bus clock is taken from system clock (150MHz) and LPC55S28 has 4 x 24-bit channels on MRT0.&lt;/P&gt;&lt;P&gt;Thanks.&lt;/P&gt;</description>
      <pubDate>Thu, 03 Jun 2021 20:53:26 GMT</pubDate>
      <guid>https://community.nxp.com/t5/LPC-Microcontrollers/Multiple-channels-of-Multi-Rate-Timer-MRT-on-LPC55S28/m-p/1287045#M45272</guid>
      <dc:creator>vanska</dc:creator>
      <dc:date>2021-06-03T20:53:26Z</dc:date>
    </item>
    <item>
      <title>Re: Multiple channels of Multi-Rate Timer (MRT) on LPC55S28</title>
      <link>https://community.nxp.com/t5/LPC-Microcontrollers/Multiple-channels-of-Multi-Rate-Timer-MRT-on-LPC55S28/m-p/1287283#M45284</link>
      <description>&lt;P&gt;Hi,&lt;/P&gt;
&lt;P&gt;It appears that your code has bug.&lt;/P&gt;
&lt;P&gt;You would like to implement a repeated fixed period interrupt with different periods based on multiple channels of MRT module, but when the period is longer than what the 24 bits of INTVAL[x] can represents, it uses software counting mode to enlarge the period. So I think your code has bugs, I just changed one channel, pls modify the other channels yourself.&lt;/P&gt;
&lt;LI-CODE lang="c"&gt;void MRT0_IRQHandler(void)
{
    if (MRT_GetStatusFlags(MRT0, kMRT_Channel_0))   // tried also "== 0x3" but same result
    {
        /* Clear interrupt flag.*/
        MRT_ClearStatusFlags(MRT0, kMRT_Channel_0, kMRT_TimerInterruptFlag);
        if (mrtEnableCount0 == true)
        {
            mrtCountValue0++;
            if (mrtCountValue0 == (1 &amp;lt;&amp;lt; mrtDividerValue0))
            {
                mrtIsrFlag0 = true;
                mrtCountValue0=0; //Rong write
                count0++;
            }
        }
        else
        {
            mrtIsrFlag0 = false;
            count0++;
        }
    }
&lt;/LI-CODE&gt;
&lt;P&gt;Pls have a try.&lt;/P&gt;
&lt;P&gt;Hope it can help you&lt;/P&gt;
&lt;P&gt;BR&lt;/P&gt;
&lt;P&gt;XiangJun Rong&lt;/P&gt;</description>
      <pubDate>Fri, 04 Jun 2021 06:14:11 GMT</pubDate>
      <guid>https://community.nxp.com/t5/LPC-Microcontrollers/Multiple-channels-of-Multi-Rate-Timer-MRT-on-LPC55S28/m-p/1287283#M45284</guid>
      <dc:creator>xiangjun_rong</dc:creator>
      <dc:date>2021-06-04T06:14:11Z</dc:date>
    </item>
    <item>
      <title>Re: Multiple channels of Multi-Rate Timer (MRT) on LPC55S28</title>
      <link>https://community.nxp.com/t5/LPC-Microcontrollers/Multiple-channels-of-Multi-Rate-Timer-MRT-on-LPC55S28/m-p/1287304#M45286</link>
      <description>&lt;P&gt;Thanks for your reply &lt;a href="https://community.nxp.com/t5/user/viewprofilepage/user-id/26034"&gt;@xiangjun_rong&lt;/a&gt;!&lt;/P&gt;&lt;P&gt;Unfortunately that does not fix the problem. The software counters are cleared in the super loop instead of ISR. That's the way it was done in the example.&lt;/P&gt;</description>
      <pubDate>Fri, 04 Jun 2021 06:43:22 GMT</pubDate>
      <guid>https://community.nxp.com/t5/LPC-Microcontrollers/Multiple-channels-of-Multi-Rate-Timer-MRT-on-LPC55S28/m-p/1287304#M45286</guid>
      <dc:creator>vanska</dc:creator>
      <dc:date>2021-06-04T06:43:22Z</dc:date>
    </item>
    <item>
      <title>Re: Multiple channels of Multi-Rate Timer (MRT) on LPC55S28</title>
      <link>https://community.nxp.com/t5/LPC-Microcontrollers/Multiple-channels-of-Multi-Rate-Timer-MRT-on-LPC55S28/m-p/1287327#M45287</link>
      <description>&lt;P&gt;Hi,&lt;/P&gt;
&lt;P&gt;Maybe&amp;nbsp; the printf() function has issue, it takes a long time.&lt;/P&gt;
&lt;P&gt;Can you have a test, you delete all the printf() in the while(true) loop, and declare a two dimension uint32_t array, you can save both the channel and counter to the array, then check if the time value are similar for different channels.&lt;/P&gt;
&lt;P&gt;BR&lt;/P&gt;
&lt;P&gt;XiangJun Rong&lt;/P&gt;</description>
      <pubDate>Fri, 04 Jun 2021 07:13:53 GMT</pubDate>
      <guid>https://community.nxp.com/t5/LPC-Microcontrollers/Multiple-channels-of-Multi-Rate-Timer-MRT-on-LPC55S28/m-p/1287327#M45287</guid>
      <dc:creator>xiangjun_rong</dc:creator>
      <dc:date>2021-06-04T07:13:53Z</dc:date>
    </item>
    <item>
      <title>Re: Multiple channels of Multi-Rate Timer (MRT) on LPC55S28</title>
      <link>https://community.nxp.com/t5/LPC-Microcontrollers/Multiple-channels-of-Multi-Rate-Timer-MRT-on-LPC55S28/m-p/1287334#M45289</link>
      <description>&lt;P&gt;Hi,&lt;/P&gt;&lt;P&gt;I actually suspected printf() also, so I already tested that earlier - not with an array but breakpoint instead. But since periods are relatively long, printf() did not have any effect. The outcome is exactly the same.&lt;/P&gt;</description>
      <pubDate>Fri, 04 Jun 2021 07:20:16 GMT</pubDate>
      <guid>https://community.nxp.com/t5/LPC-Microcontrollers/Multiple-channels-of-Multi-Rate-Timer-MRT-on-LPC55S28/m-p/1287334#M45289</guid>
      <dc:creator>vanska</dc:creator>
      <dc:date>2021-06-04T07:20:16Z</dc:date>
    </item>
    <item>
      <title>Re: Multiple channels of Multi-Rate Timer (MRT) on LPC55S28</title>
      <link>https://community.nxp.com/t5/LPC-Microcontrollers/Multiple-channels-of-Multi-Rate-Timer-MRT-on-LPC55S28/m-p/1288250#M45327</link>
      <description>&lt;P&gt;More debugging results. I removed all the code related to channels 2 and 3, and continued testing with only channels 0 and 1 to simplify things.&lt;/P&gt;&lt;P&gt;I set the following periods:&lt;/P&gt;&lt;LI-CODE lang="c"&gt;static const uint32_t CH0_INTERVAL_MS       = 10U;
static const uint32_t CH1_INTERVAL_MS       = 1000U;&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;And removed PRINTF overhead from super loop:&lt;/P&gt;&lt;LI-CODE lang="c"&gt;    while (true)
    {
        /* Check whether interrupt occurred and toggle LED */
        if (true == mrtIsrFlag0)
        {          
            if (count0 == 6000U)    // 60 sec == 10 msec * 6000 
            {
                PRINTF("\r\n [0] %u", count0 * CH0_INTERVAL_MS);
                PRINTF("\r\n [1] %u", count1 * CH1_INTERVAL_MS);
                for(;;);
            }

            mrtCountValue0 = 0;
            mrtIsrFlag0    = false;
        }
        if (true == mrtIsrFlag1)
        {
            if (count1 == 60U)     // 60 sec == 1000 msec * 60
            {
                PRINTF("\r\n [1] %u", count1 * CH1_INTERVAL_MS);
                PRINTF("\r\n [0] %u", count0 * CH0_INTERVAL_MS);
                for(;;);
            }

            mrtCountValue1 = 0;
            mrtIsrFlag1    = false;
        }
    }&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I used stopwatch to see how long it takes for either if statement to execute. After little less than &lt;STRONG&gt;10 seconds&lt;/STRONG&gt; the "60 seconds" limit of channel 1 was reached:&lt;/P&gt;&lt;BLOCKQUOTE&gt;&lt;P&gt;Starting channel No.0 ...&lt;BR /&gt;Starting channel No.1 ...&lt;BR /&gt;mrtDividerValue0 = 0 (10 msec)&lt;BR /&gt;mrtDividerValue1 = 4 (1000 msec)&lt;BR /&gt;[1] 60000&lt;BR /&gt;[0] 9600&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;P&gt;Then I commented out that if statement to verify how long it takes for channel 0 to reach its limit:&lt;/P&gt;&lt;LI-CODE lang="c"&gt;    while (true)
    {
        /* Check whether interrupt occurred and toggle LED */
        if (true == mrtIsrFlag0)
        {          
            if (count0 == 6000U)    // 60 sec == 10 msec * 6000 
            {
                PRINTF("\r\n [0] %u", count0 * CH0_INTERVAL_MS);
                PRINTF("\r\n [1] %u", count1 * CH1_INTERVAL_MS);
                for(;;);
            }

            mrtCountValue0 = 0;
            mrtIsrFlag0    = false;
        }
        if (true == mrtIsrFlag1)
        {
//            if (count1 == 60U)     // 60 sec == 1000 msec * 60
//            {
//                PRINTF("\r\n [1] %u", count1 * CH1_INTERVAL_MS);
//                PRINTF("\r\n [0] %u", count0 * CH0_INTERVAL_MS);
//                for(;;);
//            }

            mrtCountValue1 = 0;
            mrtIsrFlag1    = false;
        }
    }&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;And it took exactly &lt;STRONG&gt;60 seconds&lt;/STRONG&gt;:&lt;/P&gt;&lt;BLOCKQUOTE&gt;&lt;P&gt;Starting channel No.0 ...&lt;BR /&gt;Starting channel No.1 ...&lt;BR /&gt;mrtDividerValue0 = 0 (10 msec)&lt;BR /&gt;mrtDividerValue1 = 4 (1000 msec)&lt;BR /&gt;[0] 60000&lt;BR /&gt;[1] 375000&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;P&gt;So channel 0 works alright, but the counter of channel 1 is updated 625% (375/60) more often than it should.&lt;/P&gt;&lt;P&gt;Then I noticed that I had completely forgot to do the same initializations for other channels than channel 0. I fixed that by:&lt;/P&gt;&lt;LI-CODE lang="c"&gt;    MRT_SetupChannelMode(MRT0, kMRT_Channel_0, kMRT_RepeatMode);
    MRT_SetupChannelMode(MRT0, kMRT_Channel_1, kMRT_RepeatMode);  // this was missing

    MRT_EnableInterrupts(MRT0, kMRT_Channel_0, kMRT_TimerInterruptEnable);
    MRT_EnableInterrupts(MRT0, kMRT_Channel_1, kMRT_TimerInterruptEnable);  // so was this&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Now I was quite confident that it would finally work. But after around &lt;STRONG&gt;~52 seconds&lt;/STRONG&gt; I got the same result:&lt;/P&gt;&lt;BLOCKQUOTE&gt;&lt;P&gt;Starting channel No.0 ...&lt;BR /&gt;Starting channel No.1 ...&lt;BR /&gt;mrtDividerValue0 = 0 (10 msec)&lt;BR /&gt;mrtDividerValue1 = 4 (1000 msec)&lt;BR /&gt;[0] 60000&lt;BR /&gt;[1] 375000&lt;/P&gt;&lt;/BLOCKQUOTE&gt;&lt;P&gt;I'm confused. How should this work?&lt;/P&gt;</description>
      <pubDate>Mon, 07 Jun 2021 11:18:25 GMT</pubDate>
      <guid>https://community.nxp.com/t5/LPC-Microcontrollers/Multiple-channels-of-Multi-Rate-Timer-MRT-on-LPC55S28/m-p/1288250#M45327</guid>
      <dc:creator>vanska</dc:creator>
      <dc:date>2021-06-07T11:18:25Z</dc:date>
    </item>
    <item>
      <title>Re: Multiple channels of Multi-Rate Timer (MRT) on LPC55S28</title>
      <link>https://community.nxp.com/t5/LPC-Microcontrollers/Multiple-channels-of-Multi-Rate-Timer-MRT-on-LPC55S28/m-p/1288283#M45328</link>
      <description>&lt;P&gt;Found it! There were 2 problems in the code of the first post:&lt;/P&gt;&lt;UL&gt;&lt;LI&gt;Missing initializations of other channels than 0&lt;/LI&gt;&lt;LI&gt;MRT_GetStatusFlags return value must be compared to &lt;STRONG&gt;0x3&lt;/STRONG&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;These changes will resolve the issue:&lt;/P&gt;&lt;LI-CODE lang="c"&gt;-    if (MRT_GetStatusFlags(MRT0, kMRT_Channel_0))
+    if (MRT_GetStatusFlags(MRT0, kMRT_Channel_0) == (MRT_CHANNEL_STAT_INTFLAG_MASK | MRT_CHANNEL_STAT_RUN_MASK))

-    if (MRT_GetStatusFlags(MRT0, kMRT_Channel_1))
+    if (MRT_GetStatusFlags(MRT0, kMRT_Channel_1) == (MRT_CHANNEL_STAT_INTFLAG_MASK | MRT_CHANNEL_STAT_RUN_MASK))

-    if (MRT_GetStatusFlags(MRT0, kMRT_Channel_2))
+    if (MRT_GetStatusFlags(MRT0, kMRT_Channel_2) == (MRT_CHANNEL_STAT_INTFLAG_MASK | MRT_CHANNEL_STAT_RUN_MASK))

-    if (MRT_GetStatusFlags(MRT0, kMRT_Channel_3))
+    if (MRT_GetStatusFlags(MRT0, kMRT_Channel_3) == (MRT_CHANNEL_STAT_INTFLAG_MASK | MRT_CHANNEL_STAT_RUN_MASK))

     MRT_SetupChannelMode(MRT0, kMRT_Channel_0, kMRT_RepeatMode);
+    MRT_SetupChannelMode(MRT0, kMRT_Channel_1, kMRT_RepeatMode);
+    MRT_SetupChannelMode(MRT0, kMRT_Channel_2, kMRT_RepeatMode);
+    MRT_SetupChannelMode(MRT0, kMRT_Channel_3, kMRT_RepeatMode);

     MRT_EnableInterrupts(MRT0, kMRT_Channel_0, kMRT_TimerInterruptEnable);
+    MRT_EnableInterrupts(MRT0, kMRT_Channel_1, kMRT_TimerInterruptEnable);
+    MRT_EnableInterrupts(MRT0, kMRT_Channel_2, kMRT_TimerInterruptEnable);
+    MRT_EnableInterrupts(MRT0, kMRT_Channel_3, kMRT_TimerInterruptEnable);&lt;/LI-CODE&gt;</description>
      <pubDate>Mon, 07 Jun 2021 12:33:06 GMT</pubDate>
      <guid>https://community.nxp.com/t5/LPC-Microcontrollers/Multiple-channels-of-Multi-Rate-Timer-MRT-on-LPC55S28/m-p/1288283#M45328</guid>
      <dc:creator>vanska</dc:creator>
      <dc:date>2021-06-07T12:33:06Z</dc:date>
    </item>
  </channel>
</rss>

