libxr  1.0
Want to be the best embedded framework
Loading...
Searching...
No Matches
mspm0_pwm.cpp
1#include "mspm0_pwm.hpp"
2
3using namespace LibXR;
4
5static constexpr uint32_t MAX_TIMER_LOAD = 65535;
6static constexpr uint32_t MAX_PRESCALER = 256;
7static constexpr uint32_t MAX_DIVIDE_RATIO = 8;
8
9MSPM0PWM::MSPM0PWM(MSPM0PWM::Resources res)
10 : timer_(res.timer), channel_(res.channel), clock_freq_(res.clock_freq)
11{
12 ASSERT(timer_ != nullptr);
13 ASSERT(clock_freq_ > 0);
14}
15
16ErrorCode MSPM0PWM::SetDutyCycle(float value)
17{
18 if (value < 0.0f)
19 {
20 value = 0.0f;
21 }
22 if (value > 1.0f)
23 {
24 value = 1.0f;
25 }
26
27 uint32_t period = DL_Timer_getLoadValue(timer_);
28 uint32_t compare_value = 0;
29 DL_TIMER_COUNT_MODE count_mode = DL_Timer_getCounterMode(timer_);
30
31 switch (count_mode)
32 {
33 case DL_TIMER_COUNT_MODE_DOWN:
34 compare_value = static_cast<uint32_t>(static_cast<float>(period) * (1.0f - value));
35 break;
36
37 case DL_TIMER_COUNT_MODE_UP:
38 case DL_TIMER_COUNT_MODE_UP_DOWN:
39 compare_value = static_cast<uint32_t>(static_cast<float>(period) * value);
40 break;
41
42 default:
43 return ErrorCode::NOT_SUPPORT;
44 }
45
46 if (compare_value > period)
47 {
48 compare_value = period;
49 }
50
51 DL_Timer_setCaptureCompareValue(timer_, compare_value, channel_);
52
53 return ErrorCode::OK;
54}
55
57{
58 const uint32_t SOURCE_CLOCK = clock_freq_;
59 if (config.frequency > SOURCE_CLOCK || config.frequency == 0)
60 {
61 return ErrorCode::ARG_ERR;
62 }
63
64 const uint32_t TOTAL_CYCLES_NEEDED = SOURCE_CLOCK / config.frequency;
65 uint32_t min_total_prescale = (TOTAL_CYCLES_NEEDED + MAX_TIMER_LOAD) >> 16;
66 if (min_total_prescale == 0)
67 {
68 min_total_prescale = 1;
69 }
70
71 uint32_t best_div = (min_total_prescale + MAX_PRESCALER - 1) >> 8;
72 if (best_div > MAX_DIVIDE_RATIO)
73 {
74 return ErrorCode::NOT_SUPPORT; // Frequency too low
75 }
76 if (best_div == 0)
77 {
78 best_div = 1;
79 }
80
81 uint32_t best_prescaler = (min_total_prescale + best_div - 1) / best_div;
82 if (best_prescaler == 0)
83 {
84 best_prescaler = 1;
85 }
86
87 uint32_t best_load = (SOURCE_CLOCK / (best_div * best_prescaler * config.frequency));
88 if (best_load > 0)
89 {
90 best_load -= 1;
91 }
92
93 DL_Timer_ClockConfig clock_config;
94 DL_Timer_getClockConfig(timer_, &clock_config);
95
96 clock_config.divideRatio = static_cast<DL_TIMER_CLOCK_DIVIDE>(best_div - 1);
97 clock_config.prescale = static_cast<uint8_t>(best_prescaler - 1);
98
99 DL_Timer_setClockConfig(timer_, &clock_config);
100 DL_Timer_setLoadValue(timer_, best_load);
101
102 return ErrorCode::OK;
103}
104
106{
107 DL_Timer_startCounter(timer_);
108 return ErrorCode::OK;
109}
110
112{
113 DL_Timer_stopCounter(timer_);
114 return ErrorCode::OK;
115}
ErrorCode Disable()
Disables the PWM output. 禁用 PWM 输出。
ErrorCode SetDutyCycle(float value)
Sets the duty cycle of the PWM signal. 设置 PWM 信号的占空比。
Definition mspm0_pwm.cpp:16
ErrorCode SetConfig(Configuration config)
Configures the PWM settings. 配置 PWM 参数。
Definition mspm0_pwm.cpp:56
ErrorCode Enable()
Enables the PWM output. 启用 PWM 输出。
LibXR 命名空间
Definition ch32_can.hpp:14
Configuration parameters for PWM. PWM 配置参数。
Definition pwm.hpp:23
uint32_t frequency
PWM signal frequency in Hz. PWM 信号的频率(Hz)。
Definition pwm.hpp:24