File indexing completed on 2025-05-11 08:23:01
0001
0002
0003
0004
0005
0006
0007
0008 #include "fsl_qtmr.h"
0009 #ifdef __rtems__
0010 #include <bsp.h>
0011 #include <bsp/irq.h>
0012 #include <libfdt.h>
0013 #endif
0014
0015
0016 #ifndef FSL_COMPONENT_ID
0017 #define FSL_COMPONENT_ID "platform.drivers.qtmr"
0018 #endif
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030 static uint32_t QTMR_GetInstance(TMR_Type *base);
0031
0032
0033
0034
0035
0036 static TMR_Type *const s_qtmrBases[] = TMR_BASE_PTRS;
0037
0038 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0039
0040 static const clock_ip_name_t s_qtmrClocks[] = TMR_CLOCKS;
0041 #endif
0042
0043 static uint8_t s_qtmrGetPwmDutyCycle[FSL_FEATURE_SOC_TMR_COUNT] = {0U};
0044
0045
0046
0047
0048 static uint32_t QTMR_GetInstance(TMR_Type *base)
0049 {
0050 uint32_t instance;
0051
0052
0053 for (instance = 0; instance < ARRAY_SIZE(s_qtmrBases); instance++)
0054 {
0055 if (s_qtmrBases[instance] == base)
0056 {
0057 break;
0058 }
0059 }
0060
0061 assert(instance < ARRAY_SIZE(s_qtmrBases));
0062
0063 return instance;
0064 }
0065
0066 #ifdef __rtems__
0067 TMR_Type *QTMR_get_regs_from_fdt(const void *fdt, int node)
0068 {
0069 int rv;
0070 TMR_Type *regs;
0071
0072 rv = fdt_node_check_compatible(fdt, node, "nxp,imxrt-qtimer");
0073 if (rv != 0) {
0074 return NULL;
0075 }
0076 regs = imx_get_reg_of_node(fdt, node);
0077 return regs;
0078 }
0079
0080 rtems_vector_number QTMR_get_IRQ_from_fdt(const void *fdt, int node)
0081 {
0082 int rv;
0083 rtems_vector_number irq;
0084
0085 rv = fdt_node_check_compatible(fdt, node, "nxp,imxrt-qtimer");
0086 if (rv != 0) {
0087 return BSP_INTERRUPT_VECTOR_INVALID;
0088 }
0089 irq = imx_get_irq_of_node(fdt, node, 0);
0090 return irq;
0091 }
0092
0093 uint32_t QTMR_get_src_clk(TMR_Type *base)
0094 {
0095 #if IMXRT_IS_MIMXRT10xx
0096 (void) base;
0097
0098 return CLOCK_GetFreq(kCLOCK_IpgClk);
0099 #elif IMXRT_IS_MIMXRT11xx
0100 (void) base;
0101
0102 return CLOCK_GetRootClockFreq(kCLOCK_Root_Bus);
0103 #else
0104 #error Getting Timer clock frequency is not implemented for this chip
0105 #endif
0106 }
0107
0108 #endif
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118 void QTMR_Init(TMR_Type *base, qtmr_channel_selection_t channel, const qtmr_config_t *config)
0119 {
0120 assert(NULL != config);
0121
0122 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0123
0124 CLOCK_EnableClock(s_qtmrClocks[QTMR_GetInstance(base)]);
0125 #endif
0126
0127
0128 base->CHANNEL[channel].CTRL = (TMR_CTRL_PCS(config->primarySource) | TMR_CTRL_SCS(config->secondarySource));
0129
0130
0131 base->CHANNEL[channel].SCTRL =
0132 (TMR_SCTRL_EEOF(config->enableExternalForce) | TMR_SCTRL_MSTR(config->enableMasterMode));
0133
0134
0135 base->CHANNEL[channel].CSCTRL = TMR_CSCTRL_DBG_EN(config->debugMode);
0136
0137 base->CHANNEL[channel].FILT &= (uint16_t)(~(TMR_FILT_FILT_CNT_MASK | TMR_FILT_FILT_PER_MASK));
0138
0139 base->CHANNEL[channel].FILT =
0140 (TMR_FILT_FILT_CNT(config->faultFilterCount) | TMR_FILT_FILT_PER(config->faultFilterPeriod));
0141 }
0142
0143
0144
0145
0146
0147
0148
0149 void QTMR_Deinit(TMR_Type *base, qtmr_channel_selection_t channel)
0150 {
0151
0152 base->CHANNEL[channel].CTRL &= (uint16_t)(~TMR_CTRL_CM_MASK);
0153
0154 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0155
0156 CLOCK_DisableClock(s_qtmrClocks[QTMR_GetInstance(base)]);
0157 #endif
0158 }
0159
0160
0161
0162
0163
0164
0165
0166
0167
0168
0169
0170
0171
0172
0173
0174
0175 void QTMR_GetDefaultConfig(qtmr_config_t *config)
0176 {
0177 assert(NULL != config);
0178
0179
0180 (void)memset(config, 0, sizeof(*config));
0181
0182
0183 config->debugMode = kQTMR_RunNormalInDebug;
0184
0185 config->enableExternalForce = false;
0186
0187 config->enableMasterMode = false;
0188
0189 config->faultFilterCount = 0;
0190
0191 config->faultFilterPeriod = 0;
0192
0193 config->primarySource = kQTMR_ClockDivide_2;
0194
0195 config->secondarySource = kQTMR_Counter0InputPin;
0196 }
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210
0211
0212
0213
0214
0215 status_t QTMR_SetupPwm(TMR_Type *base,
0216 qtmr_channel_selection_t channel,
0217 uint32_t pwmFreqHz,
0218 uint8_t dutyCyclePercent,
0219 bool outputPolarity,
0220 uint32_t srcClock_Hz)
0221 {
0222 uint32_t periodCount, highCount, lowCount;
0223 uint16_t reg;
0224 status_t status;
0225
0226 if (dutyCyclePercent <= 100U)
0227 {
0228
0229 base->CHANNEL[channel].SCTRL |= (TMR_SCTRL_FORCE_MASK | TMR_SCTRL_OEN_MASK);
0230
0231
0232 periodCount = srcClock_Hz / pwmFreqHz;
0233 highCount = periodCount * dutyCyclePercent / 100U;
0234 lowCount = periodCount - highCount;
0235
0236 if (highCount > 0U)
0237 {
0238 highCount -= 1U;
0239 }
0240 if (lowCount > 0U)
0241 {
0242 lowCount -= 1U;
0243 }
0244
0245 if ((highCount > 0xFFFFU) || (lowCount > 0xFFFFU))
0246 {
0247
0248 return kStatus_Fail;
0249 }
0250
0251
0252 base->CHANNEL[channel].COMP1 = (uint16_t)lowCount;
0253 base->CHANNEL[channel].COMP2 = (uint16_t)highCount;
0254
0255
0256 base->CHANNEL[channel].CMPLD1 = (uint16_t)lowCount;
0257 base->CHANNEL[channel].CMPLD2 = (uint16_t)highCount;
0258
0259 reg = base->CHANNEL[channel].CSCTRL;
0260
0261
0262
0263 reg &= (uint16_t)(~(TMR_CSCTRL_CL1_MASK | TMR_CSCTRL_CL2_MASK));
0264 reg |= (TMR_CSCTRL_CL1(kQTMR_LoadOnComp2) | TMR_CSCTRL_CL2(kQTMR_LoadOnComp1));
0265 base->CHANNEL[channel].CSCTRL = reg;
0266
0267 if (outputPolarity)
0268 {
0269
0270 base->CHANNEL[channel].SCTRL |= TMR_SCTRL_OPS_MASK;
0271 }
0272 else
0273 {
0274
0275 base->CHANNEL[channel].SCTRL &= ~(uint16_t)TMR_SCTRL_OPS_MASK;
0276 }
0277
0278 reg = base->CHANNEL[channel].CTRL;
0279 reg &= ~(uint16_t)TMR_CTRL_OUTMODE_MASK;
0280 if (dutyCyclePercent == 100U)
0281 {
0282
0283 reg |= (TMR_CTRL_LENGTH_MASK | TMR_CTRL_OUTMODE(kQTMR_SetOnCompare));
0284 }
0285 else if (dutyCyclePercent == 0U)
0286 {
0287
0288 reg |= (TMR_CTRL_LENGTH_MASK | TMR_CTRL_OUTMODE(kQTMR_ClearOnCompare));
0289 }
0290 else
0291 {
0292
0293 reg |= (TMR_CTRL_LENGTH_MASK | TMR_CTRL_OUTMODE(kQTMR_ToggleOnAltCompareReg));
0294 }
0295
0296 base->CHANNEL[channel].CTRL = reg;
0297
0298
0299 s_qtmrGetPwmDutyCycle[channel] = dutyCyclePercent;
0300
0301 status = kStatus_Success;
0302 }
0303 else
0304 {
0305
0306 status = kStatus_Fail;
0307 }
0308
0309 return status;
0310 }
0311
0312
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323
0324 void QTMR_SetupInputCapture(TMR_Type *base,
0325 qtmr_channel_selection_t channel,
0326 qtmr_input_source_t capturePin,
0327 bool inputPolarity,
0328 bool reloadOnCapture,
0329 qtmr_input_capture_edge_t captureMode)
0330 {
0331 uint16_t reg;
0332
0333
0334 reg = base->CHANNEL[channel].CTRL & (uint16_t)(~TMR_CTRL_SCS_MASK);
0335
0336
0337 reg |= TMR_CTRL_SCS(capturePin);
0338 base->CHANNEL[channel].CTRL = reg;
0339
0340
0341 reg = base->CHANNEL[channel].SCTRL &
0342 (uint16_t)(~(TMR_SCTRL_IPS_MASK | TMR_SCTRL_CAPTURE_MODE_MASK | TMR_SCTRL_OEN_MASK));
0343
0344 reg |= (TMR_SCTRL_IPS(inputPolarity) | TMR_SCTRL_CAPTURE_MODE(captureMode));
0345 base->CHANNEL[channel].SCTRL = reg;
0346
0347
0348 if (reloadOnCapture)
0349 {
0350 base->CHANNEL[channel].CSCTRL |= TMR_CSCTRL_ROC_MASK;
0351 }
0352 else
0353 {
0354 base->CHANNEL[channel].CSCTRL &= (uint16_t)(~TMR_CSCTRL_ROC_MASK);
0355 }
0356 }
0357
0358
0359
0360
0361
0362
0363
0364
0365
0366 void QTMR_EnableInterrupts(TMR_Type *base, qtmr_channel_selection_t channel, uint32_t mask)
0367 {
0368 uint16_t reg;
0369
0370 reg = base->CHANNEL[channel].SCTRL;
0371
0372 if ((mask & (uint16_t)kQTMR_CompareInterruptEnable) != 0UL)
0373 {
0374 reg |= TMR_SCTRL_TCFIE_MASK;
0375 }
0376
0377 if ((mask & (uint16_t)kQTMR_OverflowInterruptEnable) != 0UL)
0378 {
0379 reg |= TMR_SCTRL_TOFIE_MASK;
0380 }
0381
0382 if ((mask & (uint16_t)kQTMR_EdgeInterruptEnable) != 0UL)
0383 {
0384
0385 base->CHANNEL[channel].DMA &= ~(uint16_t)TMR_DMA_IEFDE_MASK;
0386 reg |= TMR_SCTRL_IEFIE_MASK;
0387 }
0388 base->CHANNEL[channel].SCTRL = reg;
0389
0390 reg = base->CHANNEL[channel].CSCTRL;
0391
0392 if ((mask & (uint16_t)kQTMR_Compare1InterruptEnable) != 0UL)
0393 {
0394 reg |= TMR_CSCTRL_TCF1EN_MASK;
0395 }
0396
0397 if ((mask & (uint16_t)kQTMR_Compare2InterruptEnable) != 0UL)
0398 {
0399 reg |= TMR_CSCTRL_TCF2EN_MASK;
0400 }
0401 base->CHANNEL[channel].CSCTRL = reg;
0402 }
0403
0404
0405
0406
0407
0408
0409
0410
0411
0412 void QTMR_DisableInterrupts(TMR_Type *base, qtmr_channel_selection_t channel, uint32_t mask)
0413 {
0414 uint16_t reg;
0415
0416 reg = base->CHANNEL[channel].SCTRL;
0417
0418 if ((mask & (uint16_t)kQTMR_CompareInterruptEnable) != 0UL)
0419 {
0420 reg &= (uint16_t)(~TMR_SCTRL_TCFIE_MASK);
0421 }
0422
0423 if ((mask & (uint16_t)kQTMR_OverflowInterruptEnable) != 0UL)
0424 {
0425 reg &= (uint16_t)(~TMR_SCTRL_TOFIE_MASK);
0426 }
0427
0428 if ((mask & (uint16_t)kQTMR_EdgeInterruptEnable) != 0UL)
0429 {
0430 reg &= (uint16_t)(~TMR_SCTRL_IEFIE_MASK);
0431 }
0432 base->CHANNEL[channel].SCTRL = reg;
0433
0434 reg = base->CHANNEL[channel].CSCTRL;
0435
0436 if ((mask & (uint16_t)kQTMR_Compare1InterruptEnable) != 0UL)
0437 {
0438 reg &= ~(uint16_t)TMR_CSCTRL_TCF1EN_MASK;
0439 }
0440
0441 if ((mask & (uint16_t)kQTMR_Compare2InterruptEnable) != 0UL)
0442 {
0443 reg &= ~(uint16_t)TMR_CSCTRL_TCF2EN_MASK;
0444 }
0445 base->CHANNEL[channel].CSCTRL = reg;
0446 }
0447
0448
0449
0450
0451
0452
0453
0454
0455
0456
0457 uint32_t QTMR_GetEnabledInterrupts(TMR_Type *base, qtmr_channel_selection_t channel)
0458 {
0459 uint32_t enabledInterrupts = 0;
0460 uint16_t reg;
0461
0462 reg = base->CHANNEL[channel].SCTRL;
0463
0464 if ((reg & TMR_SCTRL_TCFIE_MASK) != 0U)
0465 {
0466 enabledInterrupts |= (uint32_t)kQTMR_CompareFlag;
0467 }
0468
0469 if ((reg & TMR_SCTRL_TOFIE_MASK) != 0U)
0470 {
0471 enabledInterrupts |= (uint32_t)kQTMR_OverflowInterruptEnable;
0472 }
0473
0474 if ((reg & TMR_SCTRL_IEFIE_MASK) != 0U)
0475 {
0476 enabledInterrupts |= (uint32_t)kQTMR_EdgeInterruptEnable;
0477 }
0478
0479 reg = base->CHANNEL[channel].CSCTRL;
0480
0481 if ((reg & TMR_CSCTRL_TCF1EN_MASK) != 0U)
0482 {
0483 enabledInterrupts |= (uint32_t)kQTMR_Compare1InterruptEnable;
0484 }
0485
0486 if ((reg & TMR_CSCTRL_TCF2EN_MASK) != 0U)
0487 {
0488 enabledInterrupts |= (uint32_t)kQTMR_Compare2InterruptEnable;
0489 }
0490
0491 return enabledInterrupts;
0492 }
0493
0494
0495
0496
0497
0498
0499
0500
0501
0502
0503 uint32_t QTMR_GetStatus(TMR_Type *base, qtmr_channel_selection_t channel)
0504 {
0505 uint32_t statusFlags = 0;
0506 uint16_t reg;
0507
0508 reg = base->CHANNEL[channel].SCTRL;
0509
0510 if ((reg & TMR_SCTRL_TCF_MASK) != 0U)
0511 {
0512 statusFlags |= (uint32_t)kQTMR_CompareFlag;
0513 }
0514
0515 if ((reg & TMR_SCTRL_TOF_MASK) != 0U)
0516 {
0517 statusFlags |= (uint32_t)kQTMR_OverflowFlag;
0518 }
0519
0520 if ((reg & TMR_SCTRL_IEF_MASK) != 0U)
0521 {
0522 statusFlags |= (uint32_t)kQTMR_EdgeFlag;
0523 }
0524
0525 reg = base->CHANNEL[channel].CSCTRL;
0526
0527 if ((reg & TMR_CSCTRL_TCF1_MASK) != 0U)
0528 {
0529 statusFlags |= (uint32_t)kQTMR_Compare1Flag;
0530 }
0531
0532 if ((reg & TMR_CSCTRL_TCF2_MASK) != 0U)
0533 {
0534 statusFlags |= (uint32_t)kQTMR_Compare2Flag;
0535 }
0536
0537 return statusFlags;
0538 }
0539
0540
0541
0542
0543
0544
0545
0546
0547
0548 void QTMR_ClearStatusFlags(TMR_Type *base, qtmr_channel_selection_t channel, uint32_t mask)
0549 {
0550 uint16_t reg;
0551
0552 reg = base->CHANNEL[channel].SCTRL;
0553
0554 if ((mask & (uint32_t)kQTMR_CompareFlag) != 0U)
0555 {
0556 reg &= (uint16_t)(~TMR_SCTRL_TCF_MASK);
0557 }
0558
0559 if ((mask & (uint32_t)kQTMR_OverflowFlag) != 0U)
0560 {
0561 reg &= (uint16_t)(~TMR_SCTRL_TOF_MASK);
0562 }
0563
0564 if ((mask & (uint32_t)kQTMR_EdgeFlag) != 0U)
0565 {
0566 reg &= (uint16_t)(~TMR_SCTRL_IEF_MASK);
0567 }
0568 base->CHANNEL[channel].SCTRL = reg;
0569
0570 reg = base->CHANNEL[channel].CSCTRL;
0571
0572 if ((mask & (uint32_t)kQTMR_Compare1Flag) != 0U)
0573 {
0574 reg &= ~(uint16_t)TMR_CSCTRL_TCF1_MASK;
0575 }
0576
0577 if ((mask & (uint32_t)kQTMR_Compare2Flag) != 0U)
0578 {
0579 reg &= ~(uint16_t)TMR_CSCTRL_TCF2_MASK;
0580 }
0581 base->CHANNEL[channel].CSCTRL = reg;
0582 }
0583
0584
0585
0586
0587
0588
0589
0590
0591
0592
0593
0594
0595
0596
0597
0598
0599
0600
0601
0602 void QTMR_SetTimerPeriod(TMR_Type *base, qtmr_channel_selection_t channel, uint16_t ticks)
0603 {
0604
0605 base->CHANNEL[channel].CTRL |= TMR_CTRL_LENGTH_MASK;
0606
0607
0608 base->CHANNEL[channel].LOAD &= (uint16_t)(~TMR_LOAD_LOAD_MASK);
0609
0610 if ((base->CHANNEL[channel].CTRL & TMR_CTRL_DIR_MASK) != 0U)
0611 {
0612
0613 base->CHANNEL[channel].COMP2 = ticks - 1U;
0614 }
0615 else
0616 {
0617
0618 base->CHANNEL[channel].COMP1 = ticks - 1U;
0619 }
0620 }
0621
0622
0623
0624
0625
0626
0627
0628
0629
0630
0631 void QTMR_SetCompareValue(TMR_Type *base, qtmr_channel_selection_t channel, uint16_t ticks)
0632 {
0633 base->CHANNEL[channel].CTRL |= TMR_CTRL_LENGTH_MASK;
0634
0635 if ((base->CHANNEL[channel].CTRL & TMR_CTRL_DIR_MASK) != 0U)
0636 {
0637
0638 base->CHANNEL[channel].COMP2 = ticks;
0639 }
0640 else
0641 {
0642
0643 base->CHANNEL[channel].COMP1 = ticks;
0644 }
0645 }
0646
0647
0648
0649
0650
0651
0652
0653
0654
0655 void QTMR_EnableDma(TMR_Type *base, qtmr_channel_selection_t channel, uint32_t mask)
0656 {
0657 uint16_t reg;
0658
0659 reg = base->CHANNEL[channel].DMA;
0660
0661 if ((mask & (uint32_t)kQTMR_InputEdgeFlagDmaEnable) != 0U)
0662 {
0663
0664 base->CHANNEL[channel].SCTRL &= (uint16_t)(~TMR_SCTRL_IEFIE_MASK);
0665 reg |= TMR_DMA_IEFDE_MASK;
0666 }
0667
0668 if ((mask & (uint32_t)kQTMR_ComparatorPreload1DmaEnable) != 0U)
0669 {
0670 reg |= TMR_DMA_CMPLD1DE_MASK;
0671 }
0672
0673 if ((mask & (uint32_t)kQTMR_ComparatorPreload2DmaEnable) != 0U)
0674 {
0675 reg |= TMR_DMA_CMPLD2DE_MASK;
0676 }
0677 base->CHANNEL[channel].DMA = reg;
0678 }
0679
0680
0681
0682
0683
0684
0685
0686
0687
0688 void QTMR_DisableDma(TMR_Type *base, qtmr_channel_selection_t channel, uint32_t mask)
0689 {
0690 uint16_t reg;
0691
0692 reg = base->CHANNEL[channel].DMA;
0693
0694 if ((mask & (uint32_t)kQTMR_InputEdgeFlagDmaEnable) != 0U)
0695 {
0696 reg &= ~(uint16_t)TMR_DMA_IEFDE_MASK;
0697 }
0698
0699 if ((mask & (uint32_t)kQTMR_ComparatorPreload1DmaEnable) != 0U)
0700 {
0701 reg &= ~(uint16_t)TMR_DMA_CMPLD1DE_MASK;
0702 }
0703
0704 if ((mask & (uint32_t)kQTMR_ComparatorPreload2DmaEnable) != 0U)
0705 {
0706 reg &= ~(uint16_t)TMR_DMA_CMPLD2DE_MASK;
0707 }
0708 base->CHANNEL[channel].DMA = reg;
0709 }
0710
0711
0712
0713
0714
0715
0716
0717
0718
0719
0720 void QTMR_SetPwmOutputToIdle(TMR_Type *base, qtmr_channel_selection_t channel, bool idleStatus)
0721 {
0722 uint16_t reg = base->CHANNEL[channel].SCTRL;
0723
0724
0725 base->CHANNEL[channel].CTRL &= (uint16_t)(~TMR_CTRL_CM_MASK);
0726
0727 base->CHANNEL[channel].CNTR = 0U;
0728
0729 if (0U != (reg & ((uint16_t)TMR_SCTRL_OPS_MASK)))
0730 {
0731
0732 reg |= (TMR_SCTRL_FORCE_MASK | TMR_SCTRL_VAL(!idleStatus));
0733 }
0734 else
0735 {
0736
0737 reg |= (TMR_SCTRL_FORCE_MASK | TMR_SCTRL_VAL(idleStatus));
0738 }
0739 base->CHANNEL[channel].SCTRL = reg;
0740
0741 s_qtmrGetPwmDutyCycle[channel] = 0x0;
0742 }
0743
0744
0745
0746
0747
0748
0749
0750
0751
0752 uint8_t QTMR_GetPwmChannelStatus(TMR_Type *base, qtmr_channel_selection_t channel)
0753 {
0754 return s_qtmrGetPwmDutyCycle[channel];
0755 }
0756
0757
0758
0759
0760
0761
0762
0763
0764 void QTMR_SetPwmClockMode(TMR_Type *base, qtmr_channel_selection_t channel, qtmr_primary_count_source_t prescaler)
0765 {
0766 assert((uint32_t)prescaler > 7U);
0767
0768 uint16_t reg = base->CHANNEL[channel].CTRL;
0769
0770
0771 base->CHANNEL[channel].CTRL = reg & (uint16_t)(~TMR_CTRL_CM_MASK);
0772
0773
0774 reg &= (uint16_t)(~(TMR_CTRL_PCS_MASK));
0775 reg |= TMR_CTRL_PCS(prescaler);
0776 base->CHANNEL[channel].CTRL = reg;
0777 }