libxr
Embedded C++ framework for bare-metal, RTOS and Linux
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
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:
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
56uint32_t MSPM0PWM::SourceClockFromSysCfg(GPTIMER_Regs* timer, uint32_t timer_clock_hz)
57{
58 DL_Timer_ClockConfig config;
59 DL_Timer_getClockConfig(timer, &config);
60 return timer_clock_hz * (static_cast<uint32_t>(config.divideRatio) + 1U) *
61 (static_cast<uint32_t>(config.prescale) + 1U);
62}
63
65{
66 const uint32_t SOURCE_CLOCK = clock_freq_;
67 if (config.frequency > SOURCE_CLOCK || config.frequency == 0)
68 {
69 return ErrorCode::ARG_ERR;
70 }
71
72 const uint32_t TOTAL_CYCLES_NEEDED = SOURCE_CLOCK / config.frequency;
73 uint32_t min_total_prescale = (TOTAL_CYCLES_NEEDED + MAX_TIMER_LOAD) >> 16;
74 if (min_total_prescale == 0)
75 {
76 min_total_prescale = 1;
77 }
78
79 uint32_t best_div = (min_total_prescale + MAX_PRESCALER - 1) >> 8;
80 if (best_div > MAX_DIVIDE_RATIO)
81 {
82 return ErrorCode::NOT_SUPPORT; // Frequency too low
83 }
84 if (best_div == 0)
85 {
86 best_div = 1;
87 }
88
89 uint32_t best_prescaler = (min_total_prescale + best_div - 1) / best_div;
90 if (best_prescaler == 0)
91 {
92 best_prescaler = 1;
93 }
94
95 uint32_t best_load = (SOURCE_CLOCK / (best_div * best_prescaler * config.frequency));
96 if (best_load == 0)
97 {
98 return ErrorCode::NOT_SUPPORT; // Frequency too high to represent
99 }
100 best_load -= 1;
101
102 DL_Timer_ClockConfig clock_config;
103 DL_Timer_getClockConfig(timer_, &clock_config);
104
105 clock_config.divideRatio = static_cast<DL_TIMER_CLOCK_DIVIDE>(best_div - 1);
106 clock_config.prescale = static_cast<uint8_t>(best_prescaler - 1);
107
108 DL_Timer_setClockConfig(timer_, &clock_config);
109 DL_Timer_setLoadValue(timer_, best_load);
110
111 return ErrorCode::OK;
112}
113
115{
116 DL_Timer_startCounter(timer_);
117 return ErrorCode::OK;
118}
119
121{
122 DL_Timer_stopCounter(timer_);
123 return ErrorCode::OK;
124}
ErrorCode Disable()
禁用 PWM 输出 / Disables the PWM output.
static uint32_t SourceClockFromSysCfg(GPTIMER_Regs *timer, uint32_t timer_clock_hz)
由 SysConfig 的定时器时钟反推源时钟 / Source clock from SysConfig's timer clock.
Definition mspm0_pwm.cpp:56
ErrorCode SetDutyCycle(float value)
设置 PWM 信号的占空比 / Sets the duty cycle of the PWM signal.
Definition mspm0_pwm.cpp:16
ErrorCode SetConfig(Configuration config)
配置 PWM 参数 / Configures the PWM settings.
Definition mspm0_pwm.cpp:64
ErrorCode Enable()
启用 PWM 输出 / Enables the PWM output.
LibXR 命名空间 / LibXR namespace.
Definition ch32_can.hpp:14
ErrorCode
定义错误码枚举 / Defines an enumeration for error codes
@ NOT_SUPPORT
不支持 / Not supported
@ OK
操作成功 / Operation successful
@ ARG_ERR
参数错误 / Argument error
PWM 配置参数 / Configuration parameters for PWM.
Definition pwm.hpp:23
uint32_t frequency
PWM 信号的频率(Hz) / PWM signal frequency in Hz.
Definition pwm.hpp:24