<?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>topic I.MX RT1170 QTMR cascade (ms timer) in i.MX RT Crossover MCUs</title>
    <link>https://community.nxp.com/t5/i-MX-RT-Crossover-MCUs/I-MX-RT1170-QTMR-cascade-ms-timer/m-p/1858690#M30117</link>
    <description>&lt;P&gt;Hello&lt;/P&gt;&lt;DIV class=""&gt;&lt;DIV class=""&gt;&lt;DIV class=""&gt;&lt;P&gt;I'm implementing a QTMR timer in cascade mode to have the four 16-bit timers in a 64-bit one, which will be used as a software RTC.&lt;/P&gt;&lt;P&gt;Almost everything works, however I'm unable to write a value for the timer to start from that starting point.&lt;/P&gt;&lt;P&gt;Example: I started the firmware and the QTMR timer started incrementing, a date and time adjustment packet arrived with 1714696372 unix, I need the timer to start counting from this value and increment by 1 every 1ms&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;&lt;FONT size="5"&gt;Below is my example code.&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/P&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;P&gt;void QTMR1_StopTimer()&lt;/P&gt;&lt;P&gt;{&lt;/P&gt;&lt;P&gt;QTMR_StopTimer(QTMR_1_BASEADDR, QTMR_CHANNEL_0);&lt;/P&gt;&lt;P&gt;QTMR_StopTimer(QTMR_1_BASEADDR, QTMR_CHANNEL_1);&lt;/P&gt;&lt;P&gt;QTMR_StopTimer(QTMR_1_BASEADDR, QTMR_CHANNEL_2);&lt;/P&gt;&lt;P&gt;QTMR_StopTimer(QTMR_1_BASEADDR, QTMR_CHANNEL_3);&lt;/P&gt;&lt;P&gt;}&lt;/P&gt;&lt;P&gt;void QTMR1_StartTimer()&lt;/P&gt;&lt;P&gt;{&lt;/P&gt;&lt;P&gt;QTMR_StartTimer(QTMR_1_BASEADDR, QTMR_CHANNEL_3, *kQTMR_CascadeCount*);&lt;/P&gt;&lt;P&gt;/*Configure in cascade mode*/&lt;/P&gt;&lt;P&gt;QTMR_StartTimer(QTMR_1_BASEADDR, QTMR_CHANNEL_2, *kQTMR_CascadeCount*);&lt;/P&gt;&lt;P&gt;/*Configure in cascade mode*/&lt;/P&gt;&lt;P&gt;QTMR_StartTimer(QTMR_1_BASEADDR, QTMR_CHANNEL_1, *kQTMR_CascadeCount*);&lt;/P&gt;&lt;P&gt;/* Start the first channel to count on rising edge of the primary source clock */ //UP Counter&lt;/P&gt;&lt;P&gt;QTMR_StartTimer(QTMR_1_BASEADDR, QTMR_CHANNEL_0, *kQTMR_PriSrcRiseEdge*);&lt;/P&gt;&lt;P&gt;}&lt;/P&gt;&lt;P&gt;void QTMR1_SetValue(TMR_Type *base, uint64_t rtcValue)&lt;/P&gt;&lt;P&gt;{&lt;/P&gt;&lt;P&gt;// Loop for better readability and handling potential future changes&lt;/P&gt;&lt;P&gt;for (int i = 0; i &amp;lt; 4; ++i)&lt;/P&gt;&lt;P&gt;{&lt;/P&gt;&lt;P&gt;// Extract 16-bit value using bit shift and mask&lt;/P&gt;&lt;P&gt;uint16_t channelValue = (uint16_t) (rtcValue &amp;gt;&amp;gt; (16 * i)) &amp;amp; 0xFFFF;&lt;/P&gt;&lt;P&gt;// Set the value for the current channel&lt;/P&gt;&lt;P&gt;base-&amp;gt;CHANNEL[i].HOLD = channelValue;&lt;/P&gt;&lt;P&gt;}&lt;/P&gt;&lt;P&gt;}&lt;/P&gt;&lt;P&gt;uint64_t QTMR1_GetValue64Bits()&lt;/P&gt;&lt;P&gt;{&lt;/P&gt;&lt;P&gt;// Variable to store the combined value of the counters&lt;/P&gt;&lt;P&gt;uint64_t timerValue = 0;&lt;/P&gt;&lt;P&gt;// Array to hold the current values of the 16-bit counters&lt;/P&gt;&lt;P&gt;uint16_t counts[4];&lt;/P&gt;&lt;P&gt;// Retrieve the current values of the counters and store them in the array&lt;/P&gt;&lt;P&gt;counts[0] = QTMR_1_BASEADDR-&amp;gt;CHANNEL[0].HOLD;&lt;/P&gt;&lt;P&gt;counts[1] = QTMR_1_BASEADDR-&amp;gt;CHANNEL[1].HOLD;&lt;/P&gt;&lt;P&gt;counts[2] = QTMR_1_BASEADDR-&amp;gt;CHANNEL[2].HOLD;&lt;/P&gt;&lt;P&gt;counts[3] = QTMR_1_BASEADDR-&amp;gt;CHANNEL[3].HOLD;&lt;/P&gt;&lt;P&gt;// Combine the counter values into a single 64-bit value&lt;/P&gt;&lt;P&gt;for (int i = 0; i &amp;lt; 4; ++i)&lt;/P&gt;&lt;P&gt;{&lt;/P&gt;&lt;P&gt;// Convert the 16-bit counter value to a 64-bit integer and left-shift it&lt;/P&gt;&lt;P&gt;// The amount of shift varies based on the counter index in the array&lt;/P&gt;&lt;P&gt;// This ensures proper combining of the values into rtcValue&lt;/P&gt;&lt;P&gt;timerValue += (uint64_t) counts[i] &amp;lt;&amp;lt; (i * 16);&lt;/P&gt;&lt;P&gt;rtcValue = (timerValue);&lt;/P&gt;&lt;P&gt;}&lt;/P&gt;&lt;P&gt;//return (rtcValue * 1000) / QTMR_SOURCE_CLOCK_1;&lt;/P&gt;&lt;P&gt;return (rtcValue) / QTMR_SOURCE_CLOCK_1;&lt;/P&gt;&lt;P&gt;}&lt;/P&gt;&lt;P&gt;// can be placed outside main if reused)&lt;/P&gt;&lt;P&gt;int main(void)&lt;/P&gt;&lt;P&gt;{&lt;/P&gt;&lt;P&gt;uint8_t i = 0;&lt;/P&gt;&lt;P&gt;qtmr_config_t qtmrConfig;&lt;/P&gt;&lt;P&gt;/* Board pin, clock, debug console init */&lt;/P&gt;&lt;P&gt;BOARD_ConfigMPU();&lt;/P&gt;&lt;P&gt;BOARD_InitPins();&lt;/P&gt;&lt;P&gt;BOARD_BootClockRUN();&lt;/P&gt;&lt;P&gt;BOARD_InitDebugConsole();&lt;/P&gt;&lt;P&gt;uint32_t initialValueTMRB = initialValue &amp;amp; 0xFFFFFFFF; // Parte de baixo do valor inicial&lt;/P&gt;&lt;P&gt;uint32_t initialValueTMRA = (initialValue &amp;gt;&amp;gt; 32) &amp;amp; 0xFFFFFFFF; // Parte de cima do valor inicial&lt;/P&gt;&lt;P&gt;/* Board pin, clock, debug console init */&lt;/P&gt;&lt;P&gt;BOARD_ConfigMPU();&lt;/P&gt;&lt;P&gt;BOARD_InitPins();&lt;/P&gt;&lt;P&gt;BOARD_BootClockRUN();&lt;/P&gt;&lt;P&gt;BOARD_InitDebugConsole();&lt;/P&gt;&lt;P&gt;clockTimer = QTMR_SOURCE_CLOCK_128;&lt;/P&gt;&lt;P&gt;//Clock 198Mhz&lt;/P&gt;&lt;P&gt;clockSource = QTMR_SOURCE;&lt;/P&gt;&lt;P&gt;PRINTF("\r\nChain Timer use-case, 10 second tick.\n");&lt;/P&gt;&lt;P&gt;qtmrConfig.primarySource = QTMR_PRIMARY_SOURCE_1;&lt;/P&gt;&lt;P&gt;//qtmrConfig.enableMasterMode = true;&lt;/P&gt;&lt;P&gt;qtmrConfig.debugMode = *kQTMR_HaltCounter*;&lt;/P&gt;&lt;P&gt;QTMR_Init(QTMR_1_BASEADDR, QTMR_CHANNEL_0, &amp;amp;qtmrConfig);&lt;/P&gt;&lt;P&gt;/* Init the second channel to use output of the first channel as we are chaining the first channel and the second&lt;/P&gt;&lt;P&gt;* channel */&lt;/P&gt;&lt;P&gt;//qtmrConfig.enableMasterMode = false;&lt;/P&gt;&lt;P&gt;qtmrConfig.primarySource = QTMR_ClockCounterOutput_0;&lt;/P&gt;&lt;P&gt;QTMR_Init(QTMR_1_BASEADDR, QTMR_CHANNEL_1, &amp;amp;qtmrConfig);&lt;/P&gt;&lt;P&gt;qtmrConfig.primarySource = QTMR_ClockCounterOutput_1;&lt;/P&gt;&lt;P&gt;QTMR_Init(QTMR_1_BASEADDR, QTMR_CHANNEL_2, &amp;amp;qtmrConfig);&lt;/P&gt;&lt;P&gt;qtmrConfig.primarySource = QTMR_ClockCounterOutput_2;&lt;/P&gt;&lt;P&gt;QTMR_Init(QTMR_1_BASEADDR, QTMR_CHANNEL_3, &amp;amp;qtmrConfig);&lt;/P&gt;&lt;P&gt;//TMR&lt;/P&gt;&lt;P&gt;//QTMR_SetTimerPeriod(QTMR_1_BASEADDR, QTMR_CHANNEL_0,MSEC_TO_COUNT(1U, QTMR_SOURCE_CLOCK_128));&lt;/P&gt;&lt;P&gt;/* Set period in channels */&lt;/P&gt;&lt;P&gt;// for (int qtmrChannel = 0; qtmrChannel &amp;lt; 4; qtmrChannel++)&lt;/P&gt;&lt;P&gt;// {&lt;/P&gt;&lt;P&gt;// QTMR_SetTimerPeriod(QTMR_1_BASEADDR, qtmrChannel, (uint16_t)( initialValue &amp;gt;&amp;gt; (i * 16)));&lt;/P&gt;&lt;P&gt;// }&lt;/P&gt;&lt;P&gt;QTMR1_SetValue(QTMR_1_BASEADDR, initalValueUnix);&lt;/P&gt;&lt;P&gt;QTMR1_SetValue(QTMR_1_BASEADDR, initialValue);&lt;/P&gt;&lt;P&gt;QTMR_SetTimerPeriod(QTMR_1_BASEADDR, QTMR_CHANNEL_0, 0x0);&lt;/P&gt;&lt;P&gt;QTMR_SetTimerPeriod(QTMR_1_BASEADDR, QTMR_CHANNEL_1, 0x0);&lt;/P&gt;&lt;P&gt;QTMR_SetTimerPeriod(QTMR_1_BASEADDR, QTMR_CHANNEL_2, 0x0);&lt;/P&gt;&lt;P&gt;QTMR_SetTimerPeriod(QTMR_1_BASEADDR, QTMR_CHANNEL_3, 0x0);&lt;/P&gt;&lt;P&gt;/*Set load value */&lt;/P&gt;&lt;P&gt;/*Configure in cascade mode*/&lt;/P&gt;&lt;P&gt;QTMR_StartTimer(QTMR_1_BASEADDR, QTMR_CHANNEL_3, *kQTMR_CascadeCount*);&lt;/P&gt;&lt;P&gt;/*Configure in cascade mode*/&lt;/P&gt;&lt;P&gt;QTMR_StartTimer(QTMR_1_BASEADDR, QTMR_CHANNEL_2, *kQTMR_CascadeCount*);&lt;/P&gt;&lt;P&gt;/*Configure in cascade mode*/&lt;/P&gt;&lt;P&gt;QTMR_StartTimer(QTMR_1_BASEADDR, QTMR_CHANNEL_1, *kQTMR_CascadeCount*);&lt;/P&gt;&lt;P&gt;/* Start the first channel to count on rising edge of the primary source clock */ //UP Counter&lt;/P&gt;&lt;P&gt;QTMR_StartTimer(QTMR_1_BASEADDR, QTMR_CHANNEL_0, *kQTMR_PriSrcRiseEdge*);&lt;/P&gt;&lt;P&gt;for (i = 0; i &amp;lt; 5; i++) {&lt;/P&gt;&lt;P&gt;/* Check whether compare interrupt occurs*/&lt;/P&gt;&lt;P&gt;while (!(qtmrIsrFlag)) {&lt;/P&gt;&lt;P&gt;hold0 = QTMR_1_BASEADDR-&amp;gt;CHANNEL[0].HOLD;&lt;/P&gt;&lt;P&gt;hold1 = QTMR_1_BASEADDR-&amp;gt;CHANNEL[1].HOLD;&lt;/P&gt;&lt;P&gt;hold2 = QTMR_1_BASEADDR-&amp;gt;CHANNEL[2].HOLD;&lt;/P&gt;&lt;P&gt;hold3 = QTMR_1_BASEADDR-&amp;gt;CHANNEL[3].HOLD;&lt;/P&gt;&lt;P&gt;value3 = QTMR_GetCurrentTimerCount(QTMR_1_BASEADDR, QTMR_CHANNEL_3);&lt;/P&gt;&lt;P&gt;value2 = QTMR_GetCurrentTimerCount(QTMR_1_BASEADDR, QTMR_CHANNEL_2);&lt;/P&gt;&lt;P&gt;value1 = QTMR_GetCurrentTimerCount(QTMR_1_BASEADDR, QTMR_CHANNEL_1);&lt;/P&gt;&lt;P&gt;value0 = QTMR_GetCurrentTimerCount(QTMR_1_BASEADDR, QTMR_CHANNEL_0);&lt;/P&gt;&lt;P&gt;//valueTMR1 = COUNT_TO_MSEC(get_mclk_count(),QTMR_SOURCE_CLOCK_128) ;&lt;/P&gt;&lt;P&gt;valueTMR1 = get_mclk_count();&lt;/P&gt;&lt;P&gt;valueTMR2 = get_mclk_count2();&lt;/P&gt;&lt;P&gt;value = QTMR1_GetValue64Bits();&lt;/P&gt;&lt;P&gt;if(value &amp;gt; 15 &amp;amp;&amp;amp; flag){&lt;/P&gt;&lt;P&gt;QTMR1_StopTimer();&lt;/P&gt;&lt;P&gt;QTMR_1_BASEADDR-&amp;gt;CHANNEL[0].LOAD = 0x1;&lt;/P&gt;&lt;P&gt;QTMR_1_BASEADDR-&amp;gt;CHANNEL[1].LOAD = 0x1;&lt;/P&gt;&lt;P&gt;QTMR_1_BASEADDR-&amp;gt;CHANNEL[2].LOAD = 0x1;&lt;/P&gt;&lt;P&gt;QTMR_1_BASEADDR-&amp;gt;CHANNEL[3].LOAD = 0x1;&lt;/P&gt;&lt;P&gt;// QTMR_1_BASEADDR-&amp;gt;CHANNEL[0].CTRL = 0x00;&lt;/P&gt;&lt;P&gt;// QTMR_1_BASEADDR-&amp;gt;CHANNEL[1].CTRL = 0x00;&lt;/P&gt;&lt;P&gt;// QTMR_1_BASEADDR-&amp;gt;CHANNEL[2].CTRL = 0x00;&lt;/P&gt;&lt;P&gt;// QTMR_1_BASEADDR-&amp;gt;CHANNEL[3].CTRL = 0x00;&lt;/P&gt;&lt;P&gt;QTMR1_SetValue(QTMR_1_BASEADDR, initalValueUnix);&lt;/P&gt;&lt;P&gt;QTMR1_StartTimer();&lt;/P&gt;&lt;P&gt;flag = false;&lt;/P&gt;&lt;P&gt;}&lt;/P&gt;&lt;P&gt;}&lt;/P&gt;</description>
    <pubDate>Fri, 03 May 2024 00:38:08 GMT</pubDate>
    <dc:creator>italohcx</dc:creator>
    <dc:date>2024-05-03T00:38:08Z</dc:date>
    <item>
      <title>I.MX RT1170 QTMR cascade (ms timer)</title>
      <link>https://community.nxp.com/t5/i-MX-RT-Crossover-MCUs/I-MX-RT1170-QTMR-cascade-ms-timer/m-p/1858690#M30117</link>
      <description>&lt;P&gt;Hello&lt;/P&gt;&lt;DIV class=""&gt;&lt;DIV class=""&gt;&lt;DIV class=""&gt;&lt;P&gt;I'm implementing a QTMR timer in cascade mode to have the four 16-bit timers in a 64-bit one, which will be used as a software RTC.&lt;/P&gt;&lt;P&gt;Almost everything works, however I'm unable to write a value for the timer to start from that starting point.&lt;/P&gt;&lt;P&gt;Example: I started the firmware and the QTMR timer started incrementing, a date and time adjustment packet arrived with 1714696372 unix, I need the timer to start counting from this value and increment by 1 every 1ms&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;&lt;FONT size="5"&gt;Below is my example code.&lt;/FONT&gt;&lt;/STRONG&gt;&lt;/P&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;/DIV&gt;&lt;P&gt;void QTMR1_StopTimer()&lt;/P&gt;&lt;P&gt;{&lt;/P&gt;&lt;P&gt;QTMR_StopTimer(QTMR_1_BASEADDR, QTMR_CHANNEL_0);&lt;/P&gt;&lt;P&gt;QTMR_StopTimer(QTMR_1_BASEADDR, QTMR_CHANNEL_1);&lt;/P&gt;&lt;P&gt;QTMR_StopTimer(QTMR_1_BASEADDR, QTMR_CHANNEL_2);&lt;/P&gt;&lt;P&gt;QTMR_StopTimer(QTMR_1_BASEADDR, QTMR_CHANNEL_3);&lt;/P&gt;&lt;P&gt;}&lt;/P&gt;&lt;P&gt;void QTMR1_StartTimer()&lt;/P&gt;&lt;P&gt;{&lt;/P&gt;&lt;P&gt;QTMR_StartTimer(QTMR_1_BASEADDR, QTMR_CHANNEL_3, *kQTMR_CascadeCount*);&lt;/P&gt;&lt;P&gt;/*Configure in cascade mode*/&lt;/P&gt;&lt;P&gt;QTMR_StartTimer(QTMR_1_BASEADDR, QTMR_CHANNEL_2, *kQTMR_CascadeCount*);&lt;/P&gt;&lt;P&gt;/*Configure in cascade mode*/&lt;/P&gt;&lt;P&gt;QTMR_StartTimer(QTMR_1_BASEADDR, QTMR_CHANNEL_1, *kQTMR_CascadeCount*);&lt;/P&gt;&lt;P&gt;/* Start the first channel to count on rising edge of the primary source clock */ //UP Counter&lt;/P&gt;&lt;P&gt;QTMR_StartTimer(QTMR_1_BASEADDR, QTMR_CHANNEL_0, *kQTMR_PriSrcRiseEdge*);&lt;/P&gt;&lt;P&gt;}&lt;/P&gt;&lt;P&gt;void QTMR1_SetValue(TMR_Type *base, uint64_t rtcValue)&lt;/P&gt;&lt;P&gt;{&lt;/P&gt;&lt;P&gt;// Loop for better readability and handling potential future changes&lt;/P&gt;&lt;P&gt;for (int i = 0; i &amp;lt; 4; ++i)&lt;/P&gt;&lt;P&gt;{&lt;/P&gt;&lt;P&gt;// Extract 16-bit value using bit shift and mask&lt;/P&gt;&lt;P&gt;uint16_t channelValue = (uint16_t) (rtcValue &amp;gt;&amp;gt; (16 * i)) &amp;amp; 0xFFFF;&lt;/P&gt;&lt;P&gt;// Set the value for the current channel&lt;/P&gt;&lt;P&gt;base-&amp;gt;CHANNEL[i].HOLD = channelValue;&lt;/P&gt;&lt;P&gt;}&lt;/P&gt;&lt;P&gt;}&lt;/P&gt;&lt;P&gt;uint64_t QTMR1_GetValue64Bits()&lt;/P&gt;&lt;P&gt;{&lt;/P&gt;&lt;P&gt;// Variable to store the combined value of the counters&lt;/P&gt;&lt;P&gt;uint64_t timerValue = 0;&lt;/P&gt;&lt;P&gt;// Array to hold the current values of the 16-bit counters&lt;/P&gt;&lt;P&gt;uint16_t counts[4];&lt;/P&gt;&lt;P&gt;// Retrieve the current values of the counters and store them in the array&lt;/P&gt;&lt;P&gt;counts[0] = QTMR_1_BASEADDR-&amp;gt;CHANNEL[0].HOLD;&lt;/P&gt;&lt;P&gt;counts[1] = QTMR_1_BASEADDR-&amp;gt;CHANNEL[1].HOLD;&lt;/P&gt;&lt;P&gt;counts[2] = QTMR_1_BASEADDR-&amp;gt;CHANNEL[2].HOLD;&lt;/P&gt;&lt;P&gt;counts[3] = QTMR_1_BASEADDR-&amp;gt;CHANNEL[3].HOLD;&lt;/P&gt;&lt;P&gt;// Combine the counter values into a single 64-bit value&lt;/P&gt;&lt;P&gt;for (int i = 0; i &amp;lt; 4; ++i)&lt;/P&gt;&lt;P&gt;{&lt;/P&gt;&lt;P&gt;// Convert the 16-bit counter value to a 64-bit integer and left-shift it&lt;/P&gt;&lt;P&gt;// The amount of shift varies based on the counter index in the array&lt;/P&gt;&lt;P&gt;// This ensures proper combining of the values into rtcValue&lt;/P&gt;&lt;P&gt;timerValue += (uint64_t) counts[i] &amp;lt;&amp;lt; (i * 16);&lt;/P&gt;&lt;P&gt;rtcValue = (timerValue);&lt;/P&gt;&lt;P&gt;}&lt;/P&gt;&lt;P&gt;//return (rtcValue * 1000) / QTMR_SOURCE_CLOCK_1;&lt;/P&gt;&lt;P&gt;return (rtcValue) / QTMR_SOURCE_CLOCK_1;&lt;/P&gt;&lt;P&gt;}&lt;/P&gt;&lt;P&gt;// can be placed outside main if reused)&lt;/P&gt;&lt;P&gt;int main(void)&lt;/P&gt;&lt;P&gt;{&lt;/P&gt;&lt;P&gt;uint8_t i = 0;&lt;/P&gt;&lt;P&gt;qtmr_config_t qtmrConfig;&lt;/P&gt;&lt;P&gt;/* Board pin, clock, debug console init */&lt;/P&gt;&lt;P&gt;BOARD_ConfigMPU();&lt;/P&gt;&lt;P&gt;BOARD_InitPins();&lt;/P&gt;&lt;P&gt;BOARD_BootClockRUN();&lt;/P&gt;&lt;P&gt;BOARD_InitDebugConsole();&lt;/P&gt;&lt;P&gt;uint32_t initialValueTMRB = initialValue &amp;amp; 0xFFFFFFFF; // Parte de baixo do valor inicial&lt;/P&gt;&lt;P&gt;uint32_t initialValueTMRA = (initialValue &amp;gt;&amp;gt; 32) &amp;amp; 0xFFFFFFFF; // Parte de cima do valor inicial&lt;/P&gt;&lt;P&gt;/* Board pin, clock, debug console init */&lt;/P&gt;&lt;P&gt;BOARD_ConfigMPU();&lt;/P&gt;&lt;P&gt;BOARD_InitPins();&lt;/P&gt;&lt;P&gt;BOARD_BootClockRUN();&lt;/P&gt;&lt;P&gt;BOARD_InitDebugConsole();&lt;/P&gt;&lt;P&gt;clockTimer = QTMR_SOURCE_CLOCK_128;&lt;/P&gt;&lt;P&gt;//Clock 198Mhz&lt;/P&gt;&lt;P&gt;clockSource = QTMR_SOURCE;&lt;/P&gt;&lt;P&gt;PRINTF("\r\nChain Timer use-case, 10 second tick.\n");&lt;/P&gt;&lt;P&gt;qtmrConfig.primarySource = QTMR_PRIMARY_SOURCE_1;&lt;/P&gt;&lt;P&gt;//qtmrConfig.enableMasterMode = true;&lt;/P&gt;&lt;P&gt;qtmrConfig.debugMode = *kQTMR_HaltCounter*;&lt;/P&gt;&lt;P&gt;QTMR_Init(QTMR_1_BASEADDR, QTMR_CHANNEL_0, &amp;amp;qtmrConfig);&lt;/P&gt;&lt;P&gt;/* Init the second channel to use output of the first channel as we are chaining the first channel and the second&lt;/P&gt;&lt;P&gt;* channel */&lt;/P&gt;&lt;P&gt;//qtmrConfig.enableMasterMode = false;&lt;/P&gt;&lt;P&gt;qtmrConfig.primarySource = QTMR_ClockCounterOutput_0;&lt;/P&gt;&lt;P&gt;QTMR_Init(QTMR_1_BASEADDR, QTMR_CHANNEL_1, &amp;amp;qtmrConfig);&lt;/P&gt;&lt;P&gt;qtmrConfig.primarySource = QTMR_ClockCounterOutput_1;&lt;/P&gt;&lt;P&gt;QTMR_Init(QTMR_1_BASEADDR, QTMR_CHANNEL_2, &amp;amp;qtmrConfig);&lt;/P&gt;&lt;P&gt;qtmrConfig.primarySource = QTMR_ClockCounterOutput_2;&lt;/P&gt;&lt;P&gt;QTMR_Init(QTMR_1_BASEADDR, QTMR_CHANNEL_3, &amp;amp;qtmrConfig);&lt;/P&gt;&lt;P&gt;//TMR&lt;/P&gt;&lt;P&gt;//QTMR_SetTimerPeriod(QTMR_1_BASEADDR, QTMR_CHANNEL_0,MSEC_TO_COUNT(1U, QTMR_SOURCE_CLOCK_128));&lt;/P&gt;&lt;P&gt;/* Set period in channels */&lt;/P&gt;&lt;P&gt;// for (int qtmrChannel = 0; qtmrChannel &amp;lt; 4; qtmrChannel++)&lt;/P&gt;&lt;P&gt;// {&lt;/P&gt;&lt;P&gt;// QTMR_SetTimerPeriod(QTMR_1_BASEADDR, qtmrChannel, (uint16_t)( initialValue &amp;gt;&amp;gt; (i * 16)));&lt;/P&gt;&lt;P&gt;// }&lt;/P&gt;&lt;P&gt;QTMR1_SetValue(QTMR_1_BASEADDR, initalValueUnix);&lt;/P&gt;&lt;P&gt;QTMR1_SetValue(QTMR_1_BASEADDR, initialValue);&lt;/P&gt;&lt;P&gt;QTMR_SetTimerPeriod(QTMR_1_BASEADDR, QTMR_CHANNEL_0, 0x0);&lt;/P&gt;&lt;P&gt;QTMR_SetTimerPeriod(QTMR_1_BASEADDR, QTMR_CHANNEL_1, 0x0);&lt;/P&gt;&lt;P&gt;QTMR_SetTimerPeriod(QTMR_1_BASEADDR, QTMR_CHANNEL_2, 0x0);&lt;/P&gt;&lt;P&gt;QTMR_SetTimerPeriod(QTMR_1_BASEADDR, QTMR_CHANNEL_3, 0x0);&lt;/P&gt;&lt;P&gt;/*Set load value */&lt;/P&gt;&lt;P&gt;/*Configure in cascade mode*/&lt;/P&gt;&lt;P&gt;QTMR_StartTimer(QTMR_1_BASEADDR, QTMR_CHANNEL_3, *kQTMR_CascadeCount*);&lt;/P&gt;&lt;P&gt;/*Configure in cascade mode*/&lt;/P&gt;&lt;P&gt;QTMR_StartTimer(QTMR_1_BASEADDR, QTMR_CHANNEL_2, *kQTMR_CascadeCount*);&lt;/P&gt;&lt;P&gt;/*Configure in cascade mode*/&lt;/P&gt;&lt;P&gt;QTMR_StartTimer(QTMR_1_BASEADDR, QTMR_CHANNEL_1, *kQTMR_CascadeCount*);&lt;/P&gt;&lt;P&gt;/* Start the first channel to count on rising edge of the primary source clock */ //UP Counter&lt;/P&gt;&lt;P&gt;QTMR_StartTimer(QTMR_1_BASEADDR, QTMR_CHANNEL_0, *kQTMR_PriSrcRiseEdge*);&lt;/P&gt;&lt;P&gt;for (i = 0; i &amp;lt; 5; i++) {&lt;/P&gt;&lt;P&gt;/* Check whether compare interrupt occurs*/&lt;/P&gt;&lt;P&gt;while (!(qtmrIsrFlag)) {&lt;/P&gt;&lt;P&gt;hold0 = QTMR_1_BASEADDR-&amp;gt;CHANNEL[0].HOLD;&lt;/P&gt;&lt;P&gt;hold1 = QTMR_1_BASEADDR-&amp;gt;CHANNEL[1].HOLD;&lt;/P&gt;&lt;P&gt;hold2 = QTMR_1_BASEADDR-&amp;gt;CHANNEL[2].HOLD;&lt;/P&gt;&lt;P&gt;hold3 = QTMR_1_BASEADDR-&amp;gt;CHANNEL[3].HOLD;&lt;/P&gt;&lt;P&gt;value3 = QTMR_GetCurrentTimerCount(QTMR_1_BASEADDR, QTMR_CHANNEL_3);&lt;/P&gt;&lt;P&gt;value2 = QTMR_GetCurrentTimerCount(QTMR_1_BASEADDR, QTMR_CHANNEL_2);&lt;/P&gt;&lt;P&gt;value1 = QTMR_GetCurrentTimerCount(QTMR_1_BASEADDR, QTMR_CHANNEL_1);&lt;/P&gt;&lt;P&gt;value0 = QTMR_GetCurrentTimerCount(QTMR_1_BASEADDR, QTMR_CHANNEL_0);&lt;/P&gt;&lt;P&gt;//valueTMR1 = COUNT_TO_MSEC(get_mclk_count(),QTMR_SOURCE_CLOCK_128) ;&lt;/P&gt;&lt;P&gt;valueTMR1 = get_mclk_count();&lt;/P&gt;&lt;P&gt;valueTMR2 = get_mclk_count2();&lt;/P&gt;&lt;P&gt;value = QTMR1_GetValue64Bits();&lt;/P&gt;&lt;P&gt;if(value &amp;gt; 15 &amp;amp;&amp;amp; flag){&lt;/P&gt;&lt;P&gt;QTMR1_StopTimer();&lt;/P&gt;&lt;P&gt;QTMR_1_BASEADDR-&amp;gt;CHANNEL[0].LOAD = 0x1;&lt;/P&gt;&lt;P&gt;QTMR_1_BASEADDR-&amp;gt;CHANNEL[1].LOAD = 0x1;&lt;/P&gt;&lt;P&gt;QTMR_1_BASEADDR-&amp;gt;CHANNEL[2].LOAD = 0x1;&lt;/P&gt;&lt;P&gt;QTMR_1_BASEADDR-&amp;gt;CHANNEL[3].LOAD = 0x1;&lt;/P&gt;&lt;P&gt;// QTMR_1_BASEADDR-&amp;gt;CHANNEL[0].CTRL = 0x00;&lt;/P&gt;&lt;P&gt;// QTMR_1_BASEADDR-&amp;gt;CHANNEL[1].CTRL = 0x00;&lt;/P&gt;&lt;P&gt;// QTMR_1_BASEADDR-&amp;gt;CHANNEL[2].CTRL = 0x00;&lt;/P&gt;&lt;P&gt;// QTMR_1_BASEADDR-&amp;gt;CHANNEL[3].CTRL = 0x00;&lt;/P&gt;&lt;P&gt;QTMR1_SetValue(QTMR_1_BASEADDR, initalValueUnix);&lt;/P&gt;&lt;P&gt;QTMR1_StartTimer();&lt;/P&gt;&lt;P&gt;flag = false;&lt;/P&gt;&lt;P&gt;}&lt;/P&gt;&lt;P&gt;}&lt;/P&gt;</description>
      <pubDate>Fri, 03 May 2024 00:38:08 GMT</pubDate>
      <guid>https://community.nxp.com/t5/i-MX-RT-Crossover-MCUs/I-MX-RT1170-QTMR-cascade-ms-timer/m-p/1858690#M30117</guid>
      <dc:creator>italohcx</dc:creator>
      <dc:date>2024-05-03T00:38:08Z</dc:date>
    </item>
    <item>
      <title>Re: I.MX RT1170 QTMR cascade (ms timer)</title>
      <link>https://community.nxp.com/t5/i-MX-RT-Crossover-MCUs/I-MX-RT1170-QTMR-cascade-ms-timer/m-p/1860021#M30157</link>
      <description>&lt;P style="margin: 0in; font-family: Calibri; font-size: 11.0pt;" lang="es-MX"&gt;&lt;FONT face="arial,helvetica,sans-serif"&gt;Hello &lt;a href="https://community.nxp.com/t5/user/viewprofilepage/user-id/233026"&gt;@italohcx&lt;/a&gt;&amp;nbsp;,&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="margin: 0in; font-family: Calibri; font-size: 11.0pt;" lang="es-MX"&gt;&lt;FONT face="arial,helvetica,sans-serif"&gt;To load a new count value, you need to provide the value to the "LOAD" register, instead of the "HOLD" register. As shown the reference manual in the chapter 76 called "Quad Timer":&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="arial,helvetica,sans-serif"&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Habib_Melchor_Santos_0-1715040841181.png" style="width: 400px;"&gt;&lt;img src="https://community.nxp.com/t5/image/serverpage/image-id/277326iC2F0745B0F1DFCB8/image-size/medium?v=v2&amp;amp;px=400" role="button" title="Habib_Melchor_Santos_0-1715040841181.png" alt="Habib_Melchor_Santos_0-1715040841181.png" /&gt;&lt;/span&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="margin: 0in; font-family: Calibri; font-size: 11.0pt;" lang="es-MX"&gt;&lt;FONT face="arial,helvetica,sans-serif"&gt;Also, the SDK (version 2.15.1) provides an example of function to set the period in a channel, you can find this function with the name of "QTMR_SetTimerPeriod" in the header file called "fsl_qtmr.h".&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="margin: 0in; font-family: Calibri; font-size: 11.0pt;" lang="es-MX"&gt;&lt;FONT face="arial,helvetica,sans-serif"&gt;BR,&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="margin: 0in; font-family: Calibri; font-size: 11.0pt;" lang="es-MX"&gt;&lt;FONT face="arial,helvetica,sans-serif"&gt;Habib.&lt;/FONT&gt;&lt;/P&gt;</description>
      <pubDate>Tue, 07 May 2024 00:14:44 GMT</pubDate>
      <guid>https://community.nxp.com/t5/i-MX-RT-Crossover-MCUs/I-MX-RT1170-QTMR-cascade-ms-timer/m-p/1860021#M30157</guid>
      <dc:creator>Habib_MS</dc:creator>
      <dc:date>2024-05-07T00:14:44Z</dc:date>
    </item>
    <item>
      <title>Re: I.MX RT1170 QTMR cascade (ms timer)</title>
      <link>https://community.nxp.com/t5/i-MX-RT-Crossover-MCUs/I-MX-RT1170-QTMR-cascade-ms-timer/m-p/1863446#M30265</link>
      <description>&lt;P&gt;Hello &lt;a href="https://community.nxp.com/t5/user/viewprofilepage/user-id/231807"&gt;@Habib_MS&lt;/a&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I still haven't quite understood two things:&lt;/P&gt;&lt;P&gt;the increment of the timer in relation to the clock&lt;/P&gt;&lt;P&gt;and how to load this value, because when I reload the mentioned registers the increment looks strange, outside the 1ms range.&lt;/P&gt;&lt;P&gt;BR,&lt;/P&gt;&lt;P&gt;Ítalo.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 10 May 2024 11:36:06 GMT</pubDate>
      <guid>https://community.nxp.com/t5/i-MX-RT-Crossover-MCUs/I-MX-RT1170-QTMR-cascade-ms-timer/m-p/1863446#M30265</guid>
      <dc:creator>italohcx</dc:creator>
      <dc:date>2024-05-10T11:36:06Z</dc:date>
    </item>
    <item>
      <title>Re: I.MX RT1170 QTMR cascade (ms timer)</title>
      <link>https://community.nxp.com/t5/i-MX-RT-Crossover-MCUs/I-MX-RT1170-QTMR-cascade-ms-timer/m-p/1865670#M30338</link>
      <description>&lt;P style="margin: 0in; font-family: Calibri; font-size: 11.0pt;" lang="es-MX"&gt;&lt;FONT face="arial,helvetica,sans-serif"&gt;Hello again&amp;nbsp;&lt;a href="https://community.nxp.com/t5/user/viewprofilepage/user-id/233026"&gt;@italohcx&lt;/a&gt;&amp;nbsp;,&lt;/FONT&gt;&lt;BR /&gt;&lt;FONT face="arial,helvetica,sans-serif"&gt;Answering your question, the relation that exist between the timer and the clock is how fast the timer increment a value. For example, if you have any timer with a frequency of 1Hz, the timer will increase a value in 1 seg. In your case the Qtimer has the clock frequency of the "Bus clock", in general cases the&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="margin: 0in; font-size: 11.0pt;"&gt;&lt;FONT face="arial,helvetica,sans-serif"&gt;&lt;SPAN&gt;"Bus clock" frequency is 198MHz, with this value you can obtain the period of the clock with the follow formula:&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="margin: 0in; font-size: 11.0pt;"&gt;&lt;FONT face="arial,helvetica,sans-serif"&gt;&lt;SPAN&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-center" image-alt="Habib_Melchor_Santos_3-1715718405765.png" style="width: 140px;"&gt;&lt;img src="https://community.nxp.com/t5/image/serverpage/image-id/278762iA3201A9B1C6853E9/image-dimensions/140x53?v=v2" width="140" height="53" role="button" title="Habib_Melchor_Santos_3-1715718405765.png" alt="Habib_Melchor_Santos_3-1715718405765.png" /&gt;&lt;/span&gt;&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="margin: 0in; font-size: 11.0pt;"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="margin: 0in; font-size: 11.0pt;"&gt;&lt;FONT face="arial,helvetica,sans-serif"&gt; &lt;!-- [if gte msEquation 12]&gt;&lt;m:oMath xmlns:m="http://schemas.microsoft.com/office/2004/12/omml"&gt;&lt;m:r&gt;&lt;m:t&gt;&amp;#120591;&lt;/m:t&gt;&lt;/m:r&gt;&lt;m:r&gt;&lt;m:t&gt;=&lt;/m:t&gt;&lt;/m:r&gt;&lt;m:f&gt;&lt;m:fPr&gt;&lt;m:ctrlPr/&gt;&lt;/m:fPr&gt;&lt;m:num&gt;&lt;m:r&gt;&lt;m:t&gt;1&lt;/m:t&gt;&lt;/m:r&gt;&lt;/m:num&gt;&lt;m:den&gt;&lt;m:r&gt;&lt;m:t&gt;&amp;#119865;&lt;/m:t&gt;&lt;/m:r&gt;&lt;/m:den&gt;&lt;/m:f&gt;&lt;m:r&gt;&lt;m:t&gt;=&lt;/m:t&gt;&lt;/m:r&gt;&lt;m:f&gt;&lt;m:fPr&gt;&lt;m:ctrlPr/&gt;&lt;/m:fPr&gt;&lt;m:num&gt;&lt;m:r&gt;&lt;m:t&gt;1&lt;/m:t&gt;&lt;/m:r&gt;&lt;/m:num&gt;&lt;m:den&gt;&lt;m:r&gt;&lt;m:t&gt;198&lt;/m:t&gt;&lt;/m:r&gt;&lt;m:r&gt;&lt;m:t&gt;&amp;#119872;&lt;/m:t&gt;&lt;/m:r&gt;&lt;/m:den&gt;&lt;/m:f&gt;&lt;m:r&gt;&lt;m:t&gt;.&amp;nbsp;&lt;/m:t&gt;&lt;/m:r&gt;&lt;/m:oMath&gt;&lt;![endif]--&gt;&lt;SPAN&gt;Consequently, the time of a count in your Qtimer will be 5.05&lt;/SPAN&gt;&lt;SPAN&gt;µ&lt;/SPAN&gt;&lt;SPAN&gt; Seg approx.&lt;/SPAN&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="margin: 0in; font-family: Calibri; font-size: 11.0pt;" lang="es-MX"&gt;&lt;FONT face="arial,helvetica,sans-serif"&gt;You can verify your "Bus clock" in the config tool of MCUxpresso IDE, as shows the image below:&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="margin: 0in; font-family: Calibri; font-size: 11.0pt;" lang="es-MX"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="arial,helvetica,sans-serif"&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Habib_Melchor_Santos_1-1715718329523.png" style="width: 400px;"&gt;&lt;img src="https://community.nxp.com/t5/image/serverpage/image-id/278760iC7260D5823B598E7/image-size/medium?v=v2&amp;amp;px=400" role="button" title="Habib_Melchor_Santos_1-1715718329523.png" alt="Habib_Melchor_Santos_1-1715718329523.png" /&gt;&lt;/span&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="margin: 0in; font-family: Calibri; font-size: 11.0pt;"&gt;&lt;FONT face="arial,helvetica,sans-serif"&gt;I recommend you test the SDK (version 2.15) example "evkbmimxrt1170_qtmr_timer_cm7", which has a channel configured to 1ms as you require. For the cascade configuration we do not any example, but the reference manual has a section that talks about it.&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="margin: 0in; font-family: Calibri; font-size: 11.0pt;"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="margin: 0in; font-family: Calibri; font-size: 11.0pt;"&gt;&lt;FONT face="arial,helvetica,sans-serif"&gt;Also, there is a errata about overflow flag and related interrupt, which comes with its respective workaround in the aforementioned example (Please refer to qtmr_timer.c file).&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="margin: 0in; font-family: Calibri; font-size: 11.0pt;"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="arial,helvetica,sans-serif"&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Habib_Melchor_Santos_2-1715718329524.png" style="width: 735px;"&gt;&lt;img src="https://community.nxp.com/t5/image/serverpage/image-id/278759iD7E2F19061BA463A/image-dimensions/735x65?v=v2" width="735" height="65" role="button" title="Habib_Melchor_Santos_2-1715718329524.png" alt="Habib_Melchor_Santos_2-1715718329524.png" /&gt;&lt;/span&gt;&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="margin: 0in; font-family: Calibri; font-size: 11.0pt;"&gt;&lt;FONT face="arial,helvetica,sans-serif"&gt;Please check if this error is what is causing the problem.&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="margin: 0in; font-family: Calibri; font-size: 11.0pt;"&gt;&lt;FONT face="arial,helvetica,sans-serif"&gt;BR,&lt;/FONT&gt;&lt;/P&gt;
&lt;P style="margin: 0in; font-family: Calibri; font-size: 11.0pt;"&gt;&lt;FONT face="arial,helvetica,sans-serif"&gt;Habib.&lt;/FONT&gt;&lt;/P&gt;</description>
      <pubDate>Tue, 14 May 2024 20:28:57 GMT</pubDate>
      <guid>https://community.nxp.com/t5/i-MX-RT-Crossover-MCUs/I-MX-RT1170-QTMR-cascade-ms-timer/m-p/1865670#M30338</guid>
      <dc:creator>Habib_MS</dc:creator>
      <dc:date>2024-05-14T20:28:57Z</dc:date>
    </item>
  </channel>
</rss>

