Skip to content

Commit 18ff046

Browse files
LeeChunHeiLeeChunHei
authored andcommitted
change to correct username
1 parent a4dd106 commit 18ff046

File tree

2 files changed

+272
-3
lines changed

2 files changed

+272
-3
lines changed

bsp/imxrt/libraries/MIMXRT1050/SConscript

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ if GetDepend(['BSP_USING_HWTIMER']) or GetDepend(['BSP_USING_PWM']):
3434

3535
if GetDepend(['BSP_USING_PWM']):
3636
src += ['MIMXRT1052/drivers/fsl_pwm.c']
37+
src += ['MIMXRT1052/drivers/fsl_qtmr.c']
3738

3839
if GetDepend(['BSP_USING_RTC']):
3940
src += ['MIMXRT1052/drivers/fsl_snvs_hp.c']

bsp/imxrt/libraries/drivers/drv_pwm.c

Lines changed: 271 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,22 @@
1616
#if !defined(BSP_USING_PWM1_CH0) && !defined(BSP_USING_PWM1_CH1) && !defined(BSP_USING_PWM1_CH2) && !defined(BSP_USING_PWM1_CH3) && \
1717
!defined(BSP_USING_PWM2_CH0) && !defined(BSP_USING_PWM2_CH1) && !defined(BSP_USING_PWM2_CH2) && !defined(BSP_USING_PWM2_CH3) && \
1818
!defined(BSP_USING_PWM3_CH0) && !defined(BSP_USING_PWM3_CH1) && !defined(BSP_USING_PWM3_CH2) && !defined(BSP_USING_PWM3_CH3) && \
19-
!defined(BSP_USING_PWM4_CH0) && !defined(BSP_USING_PWM4_CH1) && !defined(BSP_USING_PWM4_CH2) && !defined(BSP_USING_PWM4_CH3)
20-
#error "Please define at least one BSP_USING_PWMx_CHx"
19+
!defined(BSP_USING_PWM4_CH0) && !defined(BSP_USING_PWM4_CH1) && !defined(BSP_USING_PWM4_CH2) && !defined(BSP_USING_PWM4_CH3) && \
20+
!defined(BSP_USING_QTMR1_CH0) && !defined(BSP_USING_QTMR1_CH1) && !defined(BSP_USING_QTMR1_CH2) && !defined(BSP_USING_QTMR1_CH3) && \
21+
!defined(BSP_USING_QTMR2_CH0) && !defined(BSP_USING_QTMR2_CH1) && !defined(BSP_USING_QTMR2_CH2) && !defined(BSP_USING_QTMR2_CH3) && \
22+
!defined(BSP_USING_QTMR3_CH0) && !defined(BSP_USING_QTMR3_CH1) && !defined(BSP_USING_QTMR3_CH2) && !defined(BSP_USING_QTMR3_CH3) && \
23+
!defined(BSP_USING_QTMR4_CH0) && !defined(BSP_USING_QTMR4_CH1) && !defined(BSP_USING_QTMR4_CH2) && !defined(BSP_USING_QTMR4_CH3)
24+
#error "Please define at least one BSP_USING_PWMx_CHx or BSP_USING_QTMRx_CHx"
2125
#endif
2226

2327
#define LOG_TAG "drv.pwm"
2428
#include <drv_log.h>
2529

2630
#include <rtdevice.h>
2731
#include "fsl_pwm.h"
32+
#if defined(FSL_FEATURE_SOC_TMR_COUNT) && FSL_FEATURE_SOC_TMR_COUNT > 0
33+
#include "fsl_qtmr.h"
34+
#endif
2835
#include "drv_pwm.h"
2936

3037
#define DEFAULT_PRE 5
@@ -317,6 +324,224 @@ static rt_err_t imxrt_pwm4_init(PWM_Type *base)
317324

318325
#endif /* BSP_USING_PWM4 */
319326

327+
static rt_err_t imxrt_drv_qtmr_control(struct rt_device_pwm *device, int cmd, void *arg);
328+
329+
static struct rt_pwm_ops imxrt_drv_qtmr_ops =
330+
{
331+
.control = imxrt_drv_qtmr_control
332+
};
333+
334+
static rt_err_t imxrt_drv_qtmr_enable(struct rt_device_pwm *device, struct rt_pwm_configuration *configuration, rt_bool_t enable)
335+
{
336+
TMR_Type *base;
337+
base = (TMR_Type *)device->parent.user_data;
338+
339+
if (!enable)
340+
{
341+
QTMR_StopTimer(base, configuration->channel);
342+
base->CHANNEL[configuration->channel].SCTRL |= (TMR_SCTRL_FORCE_MASK | TMR_SCTRL_OEN_MASK);
343+
}
344+
else
345+
{
346+
QTMR_StartTimer(base, configuration->channel, kQTMR_PriSrcRiseEdge);
347+
}
348+
349+
return RT_EOK;
350+
}
351+
352+
static rt_err_t imxrt_drv_qtmr_get(struct rt_device_pwm *device, struct rt_pwm_configuration *configuration)
353+
{
354+
TMR_Type *base;
355+
rt_uint32_t high_count, low_count, clk_divider, clk_freq;
356+
357+
base = (TMR_Type *)device->parent.user_data;
358+
359+
low_count = base->CHANNEL[configuration->channel].COMP1;
360+
high_count = base->CHANNEL[configuration->channel].COMP2;
361+
clk_divider = 1 << (((base->CHANNEL[configuration->channel].CTRL & TMR_CTRL_PCS_MASK) >> TMR_CTRL_PCS_SHIFT) - 8);
362+
clk_freq = CLOCK_GetFreq(kCLOCK_IpgClk) / clk_divider;
363+
364+
configuration->period = 1000000000 / clk_freq * (high_count + low_count);
365+
configuration->pulse = 1000000000 / clk_freq * high_count;
366+
367+
return RT_EOK;
368+
}
369+
370+
static rt_err_t imxrt_drv_qtmr_set(struct rt_device_pwm *device, struct rt_pwm_configuration *configuration)
371+
{
372+
RT_ASSERT(configuration->period > 0);
373+
RT_ASSERT(configuration->pulse <= configuration->period);
374+
375+
TMR_Type *base = (TMR_Type *)device->parent.user_data;
376+
377+
rt_size_t clk_freq = CLOCK_GetFreq(kCLOCK_IpgClk) / (1 << (((base->CHANNEL[configuration->channel].CTRL & TMR_CTRL_PCS_MASK) >> TMR_CTRL_PCS_SHIFT) - 8));
378+
rt_size_t current_period_count = base->CHANNEL[configuration->channel].CMPLD1 + base->CHANNEL[configuration->channel].CMPLD2;
379+
rt_size_t period_count = clk_freq / (1000000000 / configuration->period);
380+
if (current_period_count == period_count)
381+
{
382+
rt_size_t high_count = period_count * configuration->pulse / configuration->period;
383+
rt_size_t low_count = period_count - high_count;
384+
base->CHANNEL[configuration->channel].CMPLD1 = (uint16_t)low_count;
385+
base->CHANNEL[configuration->channel].CMPLD2 = (uint16_t)high_count;
386+
}
387+
else
388+
{
389+
rt_bool_t timer_is_on = base->CHANNEL[configuration->channel].CTRL & TMR_CTRL_CM_MASK;
390+
rt_uint8_t duty = configuration->pulse * 100 / configuration->period;
391+
QTMR_StopTimer(base, configuration->channel);
392+
if (kStatus_Success != QTMR_SetupPwm(base, configuration->channel, 1000000000 / configuration->period, duty, DEFAULT_POLARITY, clk_freq))
393+
{
394+
LOG_E(LOG_TAG" setup pwm failed \n");
395+
return RT_ERROR;
396+
}
397+
if (timer_is_on)
398+
{
399+
QTMR_StartTimer(base, configuration->channel, kQTMR_PriSrcRiseEdge);
400+
}
401+
}
402+
403+
return RT_EOK;
404+
}
405+
406+
static rt_err_t imxrt_drv_qtmr_control(struct rt_device_pwm *device, int cmd, void *arg)
407+
{
408+
struct rt_pwm_configuration *configuration = (struct rt_pwm_configuration *)arg;
409+
410+
switch (cmd)
411+
{
412+
case PWM_CMD_ENABLE:
413+
return imxrt_drv_qtmr_enable(device, configuration, RT_TRUE);
414+
case PWM_CMD_DISABLE:
415+
return imxrt_drv_qtmr_enable(device, configuration, RT_FALSE);
416+
case PWM_CMD_SET:
417+
return imxrt_drv_qtmr_set(device, configuration);
418+
case PWM_CMD_GET:
419+
return imxrt_drv_qtmr_get(device, configuration);
420+
default:
421+
return RT_EINVAL;
422+
}
423+
}
424+
425+
static rt_err_t imxrt_drv_qtmr_init(TMR_Type *base, qtmr_channel_selection_t channel, uint16_t psc, uint32_t fre, uint8_t duty)
426+
{
427+
qtmr_config_t qtmr_config;
428+
rt_uint32_t qtmr_clock_freq;
429+
QTMR_GetDefaultConfig(&qtmr_config);
430+
431+
qtmr_config.primarySource = (qtmr_primary_count_source_t)(psc + 8);
432+
qtmr_clock_freq = CLOCK_GetFreq(kCLOCK_IpgClk) / (1 << psc);
433+
434+
QTMR_Init(base, channel, &qtmr_config);
435+
436+
if (kStatus_Success != QTMR_SetupPwm(base, channel, fre, duty, DEFAULT_POLARITY, qtmr_clock_freq))
437+
{
438+
LOG_E(LOG_TAG" setup pwm failed \n");
439+
return RT_ERROR;
440+
}
441+
442+
return RT_EOK;
443+
}
444+
445+
static rt_err_t imxrt_qtmr_init()
446+
{
447+
TMR_Type *base_list[] =
448+
{
449+
#ifdef BSP_USING_QTMR1
450+
TMR1,
451+
#endif
452+
#ifdef BSP_USING_QTMR2
453+
TMR2,
454+
#endif
455+
#ifdef BSP_USING_QTMR3
456+
TMR3,
457+
#endif
458+
#ifdef BSP_USING_QTMR4
459+
TMR4,
460+
#endif
461+
};
462+
463+
rt_uint8_t channel_list[] =
464+
{
465+
#ifdef BSP_USING_QTMR1
466+
#ifdef BSP_USING_QTMR1_CH0
467+
1 << 0 |
468+
#endif
469+
#ifdef BSP_USING_QTMR1_CH1
470+
1 << 1 |
471+
#endif
472+
#ifdef BSP_USING_QTMR1_CH2
473+
1 << 2 |
474+
#endif
475+
#ifdef BSP_USING_QTMR1_CH3
476+
1 << 3 |
477+
#endif
478+
0,
479+
#endif
480+
#ifdef BSP_USING_QTMR2
481+
#ifdef BSP_USING_QTMR2_CH0
482+
1 << 0 |
483+
#endif
484+
#ifdef BSP_USING_QTMR2_CH1
485+
1 << 1 |
486+
#endif
487+
#ifdef BSP_USING_QTMR2_CH2
488+
1 << 2 |
489+
#endif
490+
#ifdef BSP_USING_QTMR2_CH3
491+
1 << 3 |
492+
#endif
493+
0,
494+
#endif
495+
#ifdef BSP_USING_QTMR3
496+
#ifdef BSP_USING_QTMR3_CH0
497+
1 << 0 |
498+
#endif
499+
#ifdef BSP_USING_QTMR3_CH1
500+
1 << 1 |
501+
#endif
502+
#ifdef BSP_USING_QTMR3_CH2
503+
1 << 2 |
504+
#endif
505+
#ifdef BSP_USING_QTMR3_CH3
506+
1 << 3 |
507+
#endif
508+
0,
509+
#endif
510+
#ifdef BSP_USING_QTMR4
511+
#ifdef BSP_USING_QTMR4_CH0
512+
1 << 0 |
513+
#endif
514+
#ifdef BSP_USING_QTMR4_CH1
515+
1 << 1 |
516+
#endif
517+
#ifdef BSP_USING_QTMR4_CH2
518+
1 << 2 |
519+
#endif
520+
#ifdef BSP_USING_QTMR4_CH3
521+
1 << 3 |
522+
#endif
523+
0,
524+
#endif
525+
};
526+
527+
for (rt_uint8_t i = 0; i < sizeof(base_list)/sizeof(TMR_Type *); ++i)
528+
{
529+
for (rt_uint8_t j = 0; j < 8; ++j)
530+
{
531+
if ((channel_list[i] >> j) & 1)
532+
{
533+
if (imxrt_drv_qtmr_init(base_list[i], j, DEFAULT_PRE, DEFAULT_FRE, DEFAULT_DUTY) != RT_EOK)
534+
{
535+
return -RT_ERROR;
536+
}
537+
}
538+
}
539+
}
540+
return RT_EOK;
541+
}
542+
543+
544+
320545
int rt_hw_pwm_init(void)
321546
{
322547
rt_err_t ret = RT_EOK;
@@ -391,9 +616,52 @@ int rt_hw_pwm_init(void)
391616
}
392617
#endif /* BSP_USING_PWM4 */
393618

619+
#if defined(BSP_USING_QTMR1) || defined(BSP_USING_QTMR2) || defined(BSP_USING_QTMR3) || defined(BSP_USING_QTMR4)
620+
if (imxrt_qtmr_init() != RT_EOK)
621+
{
622+
LOG_E(LOG_TAG" init qtmr failed");
623+
}
624+
#endif
625+
626+
#ifdef BSP_USING_QTMR1
627+
static struct rt_device_pwm qtmr1_device;
628+
ret = rt_device_pwm_register(&qtmr1_device, "pwm5", &imxrt_drv_qtmr_ops, TMR1);
629+
if (ret != RT_EOK)
630+
{
631+
LOG_E("%s register failed", "pwm5");
632+
}
633+
#endif /* BSP_USING_QTMR1 */
634+
635+
#ifdef BSP_USING_QTMR2
636+
static struct rt_device_pwm qtmr2_device;
637+
ret = rt_device_pwm_register(&qtmr2_device, "pwm6", &imxrt_drv_qtmr_ops, TMR2);
638+
if (ret != RT_EOK)
639+
{
640+
LOG_E("%s register failed", "pwm6");
641+
}
642+
#endif /* BSP_USING_QTMR2 */
643+
644+
#ifdef BSP_USING_QTMR3
645+
static struct rt_device_pwm qtmr3_device;
646+
ret = rt_device_pwm_register(&qtmr3_device, "pwm7", &imxrt_drv_qtmr_ops, TMR3);
647+
if (ret != RT_EOK)
648+
{
649+
LOG_E("%s register failed", "pwm7");
650+
}
651+
#endif /* BSP_USING_QTMR3 */
652+
653+
#ifdef BSP_USING_QTMR4
654+
static struct rt_device_pwm qtmr4_device;
655+
ret = rt_device_pwm_register(&qtmr4_device, "pwm8", &imxrt_drv_qtmr_ops, TMR4);
656+
if (ret != RT_EOK)
657+
{
658+
LOG_E("%s register failed", "pwm8");
659+
}
660+
#endif /* BSP_USING_QTMR4 */
661+
394662
return ret;
395663
}
396664

397-
INIT_DEVICE_EXPORT(rt_hw_pwm_init);
665+
INIT_BOARD_EXPORT(rt_hw_pwm_init);
398666

399667
#endif /* BSP_USING_PWM */

0 commit comments

Comments
 (0)