89{
90 if (config.frequency == 0u)
91 {
92 return ErrorCode::ARG_ERR;
93 }
94
95 uint32_t clock_hz = 0u;
96
97#if LIBXR_HPM_GPTMR_PWM_FALLBACK && LIBXR_HPM_PWM_HAS_BOARD_HELPER
98 if (auto_board_init_ && gptmr_ != nullptr)
99 {
100
101
102 clock_hz = board_init_gptmr_clock(gptmr_);
103 board_init_gptmr_channel_pin(gptmr_, pwm_index_, true);
104 }
105#endif
106
107 if (clock_hz == 0u)
108 {
109 clock_hz = clock_get_frequency(clock_);
110 }
111
112 if (clock_hz == 0u)
113 {
114 return ErrorCode::INIT_ERR;
115 }
116
117 uint32_t reload = clock_hz / config.frequency;
118 if (reload == 0u || reload > 0xFFFFFFu)
119 {
120 return ErrorCode::INIT_ERR;
121 }
122 reload_ = reload;
123
124#if LIBXR_HPM_PWM_SUPPORTED
125 pwm_stop_counter(pwm_);
126
127 pwm_config_t pwm_config{};
128 pwm_cmp_config_t cmp_config{};
129
130 pwm_get_default_pwm_config(pwm_, &pwm_config);
131 pwm_get_default_cmp_config(pwm_, &cmp_config);
132
133 pwm_config.enable_output = true;
134 pwm_config.invert_output = invert_;
135 pwm_config.dead_zone_in_half_cycle = 0;
136
137 pwm_set_reload(pwm_, 0, reload_);
138 pwm_set_start_count(pwm_, 0, 0);
139
140 cmp_config.mode = pwm_cmp_mode_output_compare;
141 cmp_config.cmp = reload_ + 1;
142 cmp_config.update_trigger = pwm_shadow_register_update_on_modify;
143
144 if (pwm_setup_waveform(pwm_, pwm_index_, &pwm_config, cmp_index_, &cmp_config, 1) !=
145 status_success)
146 {
147 return ErrorCode::INIT_ERR;
148 }
149
150 pwm_issue_shadow_register_lock_event(pwm_);
151#elif LIBXR_HPM_GPTMR_PWM_FALLBACK
152 if (gptmr_ == nullptr)
153 {
154 return ErrorCode::ARG_ERR;
155 }
156
157 const uint8_t reload_cmp_index = ResolveGptmrReloadCmpIndex(cmp_index_);
158 if (reload_cmp_index == kInvalidCmpIndex)
159 {
160 return ErrorCode::ARG_ERR;
161 }
162
163
164
165 gptmr_stop_counter(gptmr_, pwm_index_);
166
167 gptmr_channel_config_t cfg;
168 gptmr_channel_get_default_config(gptmr_, &cfg);
169 cfg.mode = gptmr_work_mode_no_capture;
170 cfg.cmp_initial_polarity_high = invert_;
171 cfg.enable_cmp_output = true;
172 cfg.reload = reload_;
173 cfg.cmp[cmp_index_] = reload_ / 2u;
174 cfg.cmp[reload_cmp_index] = reload_;
175
176 if (gptmr_channel_config(gptmr_, pwm_index_, &cfg, false) != status_success)
177 {
178 return ErrorCode::INIT_ERR;
179 }
180 gptmr_channel_reset_count(gptmr_, pwm_index_);
181#else
182 return ErrorCode::NOT_SUPPORT;
183#endif
184
185 configured_ = true;
186 return ErrorCode::OK;
187}