1 /***************************************************************************//**
2 * \file cy_tcpwm_pwm.c
3 * \version 1.70
4 *
5 * \brief
6 * The source file of the tcpwm driver.
7 *
8 ********************************************************************************
9 * \copyright
10 * Copyright 2016-2021 Cypress Semiconductor Corporation
11 * SPDX-License-Identifier: Apache-2.0
12 *
13 * Licensed under the Apache License, Version 2.0 (the "License");
14 * you may not use this file except in compliance with the License.
15 * You may obtain a copy of the License at
16 *
17 * http://www.apache.org/licenses/LICENSE-2.0
18 *
19 * Unless required by applicable law or agreed to in writing, software
20 * distributed under the License is distributed on an "AS IS" BASIS,
21 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the License for the specific language governing permissions and
23 * limitations under the License.
24 *******************************************************************************/
25
26 #include "cy_tcpwm_pwm.h"
27
28 #ifdef CY_IP_MXTCPWM
29
30 #if defined(__cplusplus)
31 extern "C" {
32 #endif
33
34
35 /*******************************************************************************
36 * Function Name: Cy_TCPWM_PWM_Init
37 ****************************************************************************//**
38 *
39 * Initializes the counter in the TCPWM block for the PWM operation.
40 *
41 * \note After initialization, connected PWM output pins Drive modes
42 * are set to High-Z state. To set Drive modes as set by PWM output pins
43 * configuration, call the \ref Cy_TCPWM_PWM_Enable function.
44 *
45 * \param base
46 * The pointer to a TCPWM instance.
47 *
48 * \param cntNum
49 * The Counter instance number in the selected TCPWM.
50 *
51 * \param config
52 * The pointer to a configuration structure. See \ref cy_stc_tcpwm_pwm_config_t.
53 *
54 * \return error / status code. See \ref cy_en_tcpwm_status_t.
55 *
56 * \funcusage
57 * \snippet tcpwm/pwm/snippet/main.c snippet_Cy_TCPWM_V1_PWM_Init
58 * \snippet tcpwm/pwm/snippet/main.c snippet_Cy_TCPWM_V2_PWM_Init
59 *
60 *******************************************************************************/
Cy_TCPWM_PWM_Init(TCPWM_Type * base,uint32_t cntNum,cy_stc_tcpwm_pwm_config_t const * config)61 cy_en_tcpwm_status_t Cy_TCPWM_PWM_Init(TCPWM_Type *base, uint32_t cntNum, cy_stc_tcpwm_pwm_config_t const *config)
62 {
63 cy_en_tcpwm_status_t status = CY_TCPWM_SUCCESS;
64
65 if ((NULL != base) && (NULL != config))
66 {
67 #if (CY_IP_MXTCPWM_VERSION == 1U)
68
69 TCPWM_CNT_CTRL(base, cntNum) =
70 ((config->enableCompareSwap ? TCPWM_CNT_CTRL_AUTO_RELOAD_CC_Msk : 0UL) |
71 (config->enablePeriodSwap ? TCPWM_CNT_CTRL_AUTO_RELOAD_PERIOD_Msk : 0UL) |
72 _VAL2FLD(TCPWM_CNT_CTRL_ONE_SHOT, config->runMode) |
73 _VAL2FLD(TCPWM_CNT_CTRL_UP_DOWN_MODE, config->pwmAlignment) |
74 _VAL2FLD(TCPWM_CNT_CTRL_MODE, config->pwmMode) |
75 _VAL2FLD(TCPWM_CNT_CTRL_QUADRATURE_MODE,
76 (config->invertPWMOut | (config->invertPWMOutN << 1U))) |
77 (config->killMode << CY_TCPWM_PWM_CTRL_SYNC_KILL_OR_STOP_ON_KILL_POS) |
78 _VAL2FLD(TCPWM_CNT_CTRL_GENERIC, ((CY_TCPWM_PWM_MODE_DEADTIME == config->pwmMode) ?
79 config->deadTimeClocks : config->clockPrescaler)));
80
81 if (CY_TCPWM_PWM_MODE_PSEUDORANDOM == config->pwmMode)
82 {
83 TCPWM_CNT_COUNTER(base, cntNum) = CY_TCPWM_CNT_UP_DOWN_INIT_VAL;
84 TCPWM_CNT_TR_CTRL2(base, cntNum) = CY_TCPWM_PWM_MODE_PR;
85 }
86 else
87 {
88 if (CY_TCPWM_PWM_LEFT_ALIGN == config->pwmAlignment)
89 {
90 TCPWM_CNT_COUNTER(base, cntNum) = CY_TCPWM_CNT_UP_INIT_VAL;
91 TCPWM_CNT_TR_CTRL2(base, cntNum) = CY_TCPWM_PWM_MODE_LEFT;
92 }
93 else if (CY_TCPWM_PWM_RIGHT_ALIGN == config->pwmAlignment)
94 {
95 TCPWM_CNT_COUNTER(base, cntNum) = config->period0;
96 TCPWM_CNT_TR_CTRL2(base, cntNum) = CY_TCPWM_PWM_MODE_RIGHT;
97 }
98 else if ((CY_TCPWM_PWM_CENTER_ALIGN == config->pwmAlignment) || (CY_TCPWM_PWM_ASYMMETRIC_ALIGN == config->pwmAlignment))
99 {
100 TCPWM_CNT_COUNTER(base, cntNum) = CY_TCPWM_CNT_UP_DOWN_INIT_VAL;
101 TCPWM_CNT_TR_CTRL2(base, cntNum) = (config->swapOverflowUnderflow ? CY_TCPWM_PWM_MODE_CNTR_OR_ASYMM_SWAPPED : CY_TCPWM_PWM_MODE_CNTR_OR_ASYMM);
102 }
103 else
104 {
105 /* Invalid mode */
106 status = CY_TCPWM_UNSUPPORTED_FEATURE;
107 }
108 }
109
110 TCPWM_CNT_CC(base, cntNum) = config->compare0;
111 TCPWM_CNT_CC_BUFF(base, cntNum) = config->compare1;
112 TCPWM_CNT_PERIOD(base, cntNum) = config->period0;
113 TCPWM_CNT_PERIOD_BUFF(base, cntNum) = config->period1;
114
115 if (CY_TCPWM_INPUT_CREATOR != config->countInput)
116 {
117 TCPWM_CNT_TR_CTRL0(base, cntNum) =
118 (_VAL2FLD(TCPWM_CNT_TR_CTRL0_CAPTURE_SEL, config->swapInput) |
119 _VAL2FLD(TCPWM_CNT_TR_CTRL0_RELOAD_SEL, config->reloadInput) |
120 _VAL2FLD(TCPWM_CNT_TR_CTRL0_START_SEL, config->startInput) |
121 _VAL2FLD(TCPWM_CNT_TR_CTRL0_STOP_SEL, config->killInput) |
122 _VAL2FLD(TCPWM_CNT_TR_CTRL0_COUNT_SEL, config->countInput));
123 }
124
125 TCPWM_CNT_TR_CTRL1(base, cntNum) =
126 (_VAL2FLD(TCPWM_CNT_TR_CTRL1_CAPTURE_EDGE, config->swapInputMode) |
127 _VAL2FLD(TCPWM_CNT_TR_CTRL1_RELOAD_EDGE, config->reloadInputMode) |
128 _VAL2FLD(TCPWM_CNT_TR_CTRL1_START_EDGE, config->startInputMode) |
129 _VAL2FLD(TCPWM_CNT_TR_CTRL1_STOP_EDGE, config->killInputMode) |
130 _VAL2FLD(TCPWM_CNT_TR_CTRL1_COUNT_EDGE, config->countInputMode));
131
132 TCPWM_CNT_INTR_MASK(base, cntNum) = config->interruptSources;
133 #else
134 uint32_t grp = TCPWM_GRP_CNT_GET_GRP(cntNum);
135 bool enabled_bit = _FLD2BOOL(TCPWM_GRP_CNT_V2_CTRL_ENABLED, TCPWM_GRP_CNT_CTRL(base, grp, cntNum));
136 #if defined (CY_IP_MXS40TCPWM)
137 bool dithering_present = ((bool)TCPWM_GRP_DITHERING_PRESENT(grp));
138 #endif
139
140 TCPWM_GRP_CNT_CTRL(base, grp, cntNum) =
141 ((config->enableCompareSwap ? TCPWM_GRP_CNT_V2_CTRL_AUTO_RELOAD_CC0_Msk : 0UL) |
142 (config->enablePeriodSwap ? TCPWM_GRP_CNT_V2_CTRL_AUTO_RELOAD_PERIOD_Msk : 0UL) |
143 _VAL2FLD(TCPWM_GRP_CNT_V2_CTRL_ONE_SHOT, config->runMode) |
144 _VAL2FLD(TCPWM_GRP_CNT_V2_CTRL_MODE, config->pwmMode) |
145 _VAL2FLD(TCPWM_GRP_CNT_V2_CTRL_QUAD_ENCODING_MODE, (config->invertPWMOut | (config->invertPWMOutN << 1U))) |
146 _VAL2FLD(TCPWM_GRP_CNT_V2_CTRL_PWM_STOP_ON_KILL, (config->killMode) >> 1UL) |
147 _VAL2FLD(TCPWM_GRP_CNT_V2_CTRL_PWM_SYNC_KILL, config->killMode) |
148 _VAL2FLD(TCPWM_GRP_CNT_V2_CTRL_PWM_DISABLE_MODE, config->pwmOnDisable) |
149 (config->immediateKill ? TCPWM_GRP_CNT_V2_CTRL_PWM_IMM_KILL_Msk : 0UL) |
150 (config->reloadLineSelect ? TCPWM_GRP_CNT_V2_CTRL_AUTO_RELOAD_LINE_SEL_Msk : 0UL) |
151 #if defined (CY_IP_MXS40TCPWM)
152 _VAL2FLD(TCPWM_GRP_CNT_V3_CTRL_SWAP_ENABLED, config->buffer_swap_enable) |
153 _VAL2FLD(TCPWM_GRP_CNT_V3_CTRL_DITHEREN,(dithering_present ? ((uint32_t)config->dithering_mode) : 0UL)) |
154 _VAL2FLD(TCPWM_GRP_CNT_CTRL_KILL_LINE_POLARITY, config->kill_line_polarity) |
155 #endif /* defined (CY_IP_MXS40TCPWM) */
156 (enabled_bit ? TCPWM_GRP_CNT_V2_CTRL_ENABLED_Msk : 0UL));
157
158 if (CY_TCPWM_PWM_MODE_DEADTIME == config->pwmMode)
159 {
160 TCPWM_GRP_CNT_DT(base, grp, cntNum) =
161 (_VAL2FLD(TCPWM_GRP_CNT_V2_DT_DT_LINE_OUT_L, (uint8_t)(config->deadTimeClocks)) |
162 _VAL2FLD(TCPWM_GRP_CNT_V2_DT_DT_LINE_OUT_H, (uint8_t)(config->deadTimeClocks >> 8)) |
163 _VAL2FLD(TCPWM_GRP_CNT_V2_DT_DT_LINE_COMPL_OUT, config->deadTimeClocks_linecompl_out));
164 #if defined (CY_IP_MXS40TCPWM)
165 TCPWM_GRP_CNT_DT_BUFF(base, grp, cntNum) =
166 (_VAL2FLD(TCPWM_GRP_CNT_V2_DT_DT_LINE_OUT_L, (uint8_t)(config->deadTimeClocksBuff)) |
167 _VAL2FLD(TCPWM_GRP_CNT_V2_DT_DT_LINE_OUT_H, (uint8_t)(config->deadTimeClocksBuff >> 8)) |
168 _VAL2FLD(TCPWM_GRP_CNT_V2_DT_DT_LINE_COMPL_OUT, config->deadTimeClocksBuff_linecompl_out));
169 #endif /* defined (CY_IP_MXS40TCPWM) */
170 }
171 #if !defined (CY_IP_MXS40TCPWM)
172 else
173 {
174 TCPWM_GRP_CNT_DT(base, grp, cntNum) = _VAL2FLD(TCPWM_GRP_CNT_V2_DT_DT_LINE_OUT_L, (uint8_t)config->clockPrescaler);
175 }
176 #endif /* !defined (CY_IP_MXS40TCPWM) */
177 if (CY_TCPWM_PWM_MODE_PSEUDORANDOM == config->pwmMode)
178 {
179 TCPWM_GRP_CNT_COUNTER(base, grp, cntNum) = CY_TCPWM_CNT_UP_DOWN_INIT_VAL;
180 TCPWM_GRP_CNT_TR_PWM_CTRL(base, grp, cntNum) = CY_TCPWM_PWM_MODE_PR;
181 }
182 else
183 {
184 if (CY_TCPWM_PWM_LEFT_ALIGN == config->pwmAlignment)
185 {
186 TCPWM_GRP_CNT_CTRL(base, grp, cntNum) |=
187 _VAL2FLD(TCPWM_GRP_CNT_V2_CTRL_UP_DOWN_MODE, CY_TCPWM_PWM_LEFT_ALIGN);
188 TCPWM_GRP_CNT_COUNTER(base, grp, cntNum) = CY_TCPWM_CNT_UP_INIT_VAL;
189 TCPWM_GRP_CNT_TR_PWM_CTRL(base, grp, cntNum) = (CY_TCPWM_PWM_MODE_LEFT |
190 CY_TCPWM_PWM_MODE_CC1_IGNORE);
191 }
192 else if (CY_TCPWM_PWM_RIGHT_ALIGN == config->pwmAlignment)
193 {
194 TCPWM_GRP_CNT_CTRL(base, grp, cntNum) |=
195 _VAL2FLD(TCPWM_GRP_CNT_V2_CTRL_UP_DOWN_MODE, CY_TCPWM_PWM_RIGHT_ALIGN);
196 TCPWM_GRP_CNT_COUNTER(base, grp, cntNum) = config->period0;
197 TCPWM_GRP_CNT_TR_PWM_CTRL(base, grp, cntNum) = (CY_TCPWM_PWM_MODE_RIGHT |
198 CY_TCPWM_PWM_MODE_CC1_IGNORE);
199 }
200 else if (CY_TCPWM_PWM_ASYMMETRIC_ALIGN == config->pwmAlignment)
201 {
202 TCPWM_GRP_CNT_CTRL(base, grp, cntNum) |=
203 _VAL2FLD(TCPWM_GRP_CNT_V2_CTRL_UP_DOWN_MODE, CY_TCPWM_PWM_ASYMMETRIC_ALIGN);
204 TCPWM_GRP_CNT_COUNTER(base, grp, cntNum) = CY_TCPWM_CNT_UP_DOWN_INIT_VAL;
205 TCPWM_GRP_CNT_TR_PWM_CTRL(base, grp, cntNum) = ((config->swapOverflowUnderflow ? CY_TCPWM_PWM_MODE_CNTR_OR_ASYMM_SWAPPED : CY_TCPWM_PWM_MODE_CNTR_OR_ASYMM) |
206 CY_TCPWM_PWM_MODE_CC1_IGNORE);
207 }
208 else if (CY_TCPWM_PWM_CENTER_ALIGN == config->pwmAlignment)
209 {
210 TCPWM_GRP_CNT_CTRL(base, grp, cntNum) |=
211 _VAL2FLD(TCPWM_GRP_CNT_V2_CTRL_UP_DOWN_MODE, CY_TCPWM_PWM_CENTER_ALIGN);
212 TCPWM_GRP_CNT_COUNTER(base, grp, cntNum) = CY_TCPWM_CNT_UP_DOWN_INIT_VAL;
213 TCPWM_GRP_CNT_TR_PWM_CTRL(base, grp, cntNum) = ((config->swapOverflowUnderflow ? CY_TCPWM_PWM_MODE_CNTR_OR_ASYMM_SWAPPED : CY_TCPWM_PWM_MODE_CNTR_OR_ASYMM) |
214 CY_TCPWM_PWM_MODE_CC1_IGNORE);
215 }
216 else if (TCPWM_GRP_CC1(base, grp) && (CY_TCPWM_PWM_ASYMMETRIC_CC0_CC1_ALIGN == config->pwmAlignment))
217 {
218 TCPWM_GRP_CNT_CTRL(base, grp, cntNum) |=
219 _VAL2FLD(TCPWM_GRP_CNT_V2_CTRL_UP_DOWN_MODE, CY_TCPWM_PWM_LEFT_ALIGN);
220 TCPWM_GRP_CNT_COUNTER(base, grp, cntNum) = CY_TCPWM_CNT_UP_DOWN_INIT_VAL;
221 TCPWM_GRP_CNT_TR_PWM_CTRL(base, grp, cntNum) = CY_TCPWM_PWM_MODE_ASYMM_CC0_CC1;
222 }
223 else if (TCPWM_GRP_CC1(base, grp) && (CY_TCPWM_PWM_CENTER_ASYMMETRIC_CC0_CC1_ALIGN == config->pwmAlignment))
224 {
225 TCPWM_GRP_CNT_CTRL(base, grp, cntNum) |=
226 _VAL2FLD(TCPWM_GRP_CNT_V2_CTRL_UP_DOWN_MODE, CY_TCPWM_PWM_CENTER_ALIGN);
227 TCPWM_GRP_CNT_COUNTER(base, grp, cntNum) = CY_TCPWM_CNT_UP_DOWN_INIT_VAL;
228 TCPWM_GRP_CNT_TR_PWM_CTRL(base, grp, cntNum) = CY_TCPWM_PWM_MODE_CNTR_ASYMM_CC0_CC1;
229 }
230 else
231 {
232 /* Invalid mode for specified counter group */
233 status = CY_TCPWM_UNSUPPORTED_FEATURE;
234 }
235 }
236
237 TCPWM_GRP_CNT_CC0(base, grp, cntNum) = config->compare0;
238 TCPWM_GRP_CNT_CC0_BUFF(base, grp, cntNum) = config->compare1;
239 TCPWM_GRP_CNT_PERIOD(base, grp, cntNum) = config->period0;
240
241 if (CY_TCPWM_PWM_MODE_PSEUDORANDOM == config->pwmMode)
242 {
243 TCPWM_GRP_CNT_PERIOD_BUFF(base, grp, cntNum) = config->tapsEnabled;
244 }
245 else
246 {
247 TCPWM_GRP_CNT_PERIOD_BUFF(base, grp, cntNum) = config->period1;
248 }
249 #if !defined (CY_IP_MXS40TCPWM)
250 TCPWM_GRP_CNT_TR_IN_SEL0(base, grp, cntNum) =
251 (_VAL2FLD(TCPWM_GRP_CNT_V2_TR_IN_SEL0_CAPTURE0_SEL, config->swapInput) |
252 _VAL2FLD(TCPWM_GRP_CNT_V2_TR_IN_SEL0_RELOAD_SEL, config->reloadInput) |
253 _VAL2FLD(TCPWM_GRP_CNT_V2_TR_IN_SEL0_STOP_SEL, config->killInput) |
254 _VAL2FLD(TCPWM_GRP_CNT_V2_TR_IN_SEL0_COUNT_SEL, config->countInput));
255
256 TCPWM_GRP_CNT_TR_IN_SEL1(base, grp, cntNum) = _VAL2FLD(TCPWM_GRP_CNT_V2_TR_IN_SEL1_START_SEL, config->startInput);
257
258 TCPWM_GRP_CNT_TR_IN_EDGE_SEL(base, grp, cntNum) =
259 (_VAL2FLD(TCPWM_GRP_CNT_V2_TR_IN_EDGE_SEL_CAPTURE0_EDGE, config->swapInputMode) |
260 _VAL2FLD(TCPWM_GRP_CNT_V2_TR_IN_EDGE_SEL_RELOAD_EDGE, config->reloadInputMode) |
261 _VAL2FLD(TCPWM_GRP_CNT_V2_TR_IN_EDGE_SEL_START_EDGE, config->startInputMode) |
262 _VAL2FLD(TCPWM_GRP_CNT_V2_TR_IN_EDGE_SEL_STOP_EDGE, config->killInputMode) |
263 _VAL2FLD(TCPWM_GRP_CNT_V2_TR_IN_EDGE_SEL_COUNT_EDGE, config->countInputMode));
264 #else
265 Cy_TCPWM_InputTriggerSetupWithGF(base, cntNum, CY_TCPWM_INPUT_TR_START, config->startInputMode, config->startInput, config->gf_depth);
266 Cy_TCPWM_InputTriggerSetupWithGF(base, cntNum, CY_TCPWM_INPUT_TR_RELOAD_OR_INDEX, config->reloadInputMode, config->reloadInput, config->gf_depth);
267 Cy_TCPWM_InputTriggerSetupWithGF(base, cntNum, CY_TCPWM_INPUT_TR_STOP_OR_KILL, config->killInputMode, config->killInput, config->gf_depth);
268 Cy_TCPWM_InputTriggerSetupWithGF(base, cntNum, CY_TCPWM_INPUT_TR_COUNT, config->countInputMode, config->countInput, config->gf_depth);
269 Cy_TCPWM_InputTriggerSetupWithGF(base, cntNum, CY_TCPWM_INPUT_TR_CAPTURE0, config->swapInputMode, config->swapInput, config->gf_depth);
270 #endif
271 TCPWM_GRP_CNT_TR_OUT_SEL(base, grp, cntNum) =
272 (_VAL2FLD(TCPWM_GRP_CNT_V2_TR_OUT_SEL_OUT0, config->trigger0Event) |
273 _VAL2FLD(TCPWM_GRP_CNT_V2_TR_OUT_SEL_OUT1, config->trigger1Event));
274
275 TCPWM_GRP_CNT_INTR_MASK(base, grp, cntNum) = config->interruptSources;
276
277 if(TCPWM_GRP_CC1(base, grp))
278 {
279 TCPWM_GRP_CNT_CC1(base, grp, cntNum) = config->compare2;
280 TCPWM_GRP_CNT_CC1_BUFF(base, grp, cntNum) = config->compare3;
281
282 TCPWM_GRP_CNT_CTRL(base, grp, cntNum) |=
283 (config->enableCompare1Swap ? TCPWM_GRP_CNT_V2_CTRL_AUTO_RELOAD_CC1_Msk : 0UL);
284 #if !defined (CY_IP_MXS40TCPWM)
285 TCPWM_GRP_CNT_TR_IN_SEL1(base, grp, cntNum) |= _VAL2FLD(TCPWM_GRP_CNT_V2_TR_IN_SEL1_CAPTURE1_SEL, config->kill1Input);
286 TCPWM_GRP_CNT_TR_IN_EDGE_SEL(base, grp, cntNum) |=
287 (_VAL2FLD(TCPWM_GRP_CNT_V2_TR_IN_EDGE_SEL_CAPTURE1_EDGE, config->kill1InputMode));
288 #else
289 Cy_TCPWM_InputTriggerSetupWithGF(base, cntNum, CY_TCPWM_INPUT_TR_CAPTURE1, config->kill1InputMode, config->kill1Input, config->gf_depth);
290 #endif
291 }
292
293 if(TCPWM_GRP_AMC(base, grp))
294 {
295 if(CY_TCPWM_PWM_CENTER_ASYMMETRIC_CC0_CC1_ALIGN != config->pwmAlignment)
296 {
297 TCPWM_GRP_CNT_CTRL(base, grp, cntNum) |=
298 ((config->compare0MatchUp ? TCPWM_GRP_CNT_V2_CTRL_CC0_MATCH_UP_EN_Msk : 0UL) |
299 (config->compare0MatchDown ? TCPWM_GRP_CNT_V2_CTRL_CC0_MATCH_DOWN_EN_Msk : 0UL) |
300 (config->compare1MatchUp ? TCPWM_GRP_CNT_V2_CTRL_CC1_MATCH_UP_EN_Msk : 0UL) |
301 (config->compare1MatchDown ? TCPWM_GRP_CNT_V2_CTRL_CC1_MATCH_DOWN_EN_Msk : 0UL));
302 }
303 else
304 {
305 TCPWM_GRP_CNT_CTRL(base, grp, cntNum) |= CY_TCPWM_PWM_MODE_CNTR_ASYMM_CC0_CC1_MATCH;
306 }
307 }
308 TCPWM_GRP_CNT_LINE_SEL(base, grp, cntNum) = (_VAL2FLD(TCPWM_GRP_CNT_V2_LINE_SEL_OUT_SEL, config->line_out_sel) |
309 _VAL2FLD(TCPWM_GRP_CNT_V2_LINE_SEL_COMPL_OUT_SEL, config->linecompl_out_sel));
310 TCPWM_GRP_CNT_LINE_SEL_BUFF(base, grp, cntNum) = (_VAL2FLD(TCPWM_GRP_CNT_V2_LINE_SEL_OUT_SEL, config->line_out_sel_buff) |
311 _VAL2FLD(TCPWM_GRP_CNT_V2_LINE_SEL_COMPL_OUT_SEL, config->linecompl_out_sel_buff));
312 #if defined (CY_IP_MXS40TCPWM)
313 bool hrpwm_present = ((bool)TCPWM_GRP_HRPWM_PRESENT(grp));
314 if(hrpwm_present)
315 {
316 if (config->hrpwm_enable)
317 {
318 TCPWM_GRP_CNT_HRPWM_CTRL(base, grp, cntNum) = (_VAL2FLD(TCPWM_GRP_CNT_HRPWM_CTRL_HRPWM_EN, 1UL) |
319 _VAL2FLD(TCPWM_GRP_CNT_HRPWM_CTRL_FREQ_SEL, config->hrpwm_input_freq));
320 }
321 }
322 if(config->dithering_mode != CY_TCPWM_DITHERING_DISABLE)
323 {
324 TCPWM_GRP_CNT_LFSR(base, grp, cntNum) = (_VAL2FLD(TCPWM_GRP_CNT_V3_LFSR_PLFSR, config->period_dithering_value) |
325 _VAL2FLD(TCPWM_GRP_CNT_V3_LFSR_DLFSR, config->duty_dithering_value) |
326 _VAL2FLD(TCPWM_GRP_CNT_V3_LFSR_LIMITER, config->limiter));
327 }
328 TCPWM_GRP_CNT_PS(base, grp, cntNum) = (_VAL2FLD(TCPWM_GRP_CNT_PS_PS_DIV, config->clockPrescaler));
329 #endif /*defined (CY_IP_MXS40TCPWM)*/
330 #endif /* (CY_IP_MXTCPWM_VERSION == 1U) */
331 }
332 else
333 {
334 status = CY_TCPWM_BAD_PARAM;
335 }
336
337 return(status);
338 }
339
340 /*******************************************************************************
341 * Function Name: Cy_TCPWM_PWM_DeInit
342 ****************************************************************************//**
343 *
344 * De-initializes the counter in the TCPWM block, returns register values to
345 * default.
346 *
347 * \param base
348 * The pointer to a TCPWM instance.
349 *
350 * \param cntNum
351 * The Counter instance number in the selected TCPWM.
352 *
353 * \param config
354 * The pointer to a configuration structure. See \ref cy_stc_tcpwm_pwm_config_t.
355 *
356 * \funcusage
357 * \snippet tcpwm/pwm/snippet/main.c snippet_Cy_TCPWM_PWM_DeInit
358 *
359 *******************************************************************************/
Cy_TCPWM_PWM_DeInit(TCPWM_Type * base,uint32_t cntNum,cy_stc_tcpwm_pwm_config_t const * config)360 void Cy_TCPWM_PWM_DeInit(TCPWM_Type *base, uint32_t cntNum, cy_stc_tcpwm_pwm_config_t const *config)
361 {
362 #if (CY_IP_MXTCPWM_VERSION == 1U)
363
364 TCPWM_CNT_CTRL(base, cntNum) = CY_TCPWM_CNT_CTRL_DEFAULT;
365 TCPWM_CNT_COUNTER(base, cntNum) = CY_TCPWM_CNT_COUNTER_DEFAULT;
366 TCPWM_CNT_CC(base, cntNum) = CY_TCPWM_CNT_CC_DEFAULT;
367 TCPWM_CNT_CC_BUFF(base, cntNum) = CY_TCPWM_CNT_CC_BUFF_DEFAULT;
368 TCPWM_CNT_PERIOD(base, cntNum) = CY_TCPWM_CNT_PERIOD_DEFAULT;
369 TCPWM_CNT_PERIOD_BUFF(base, cntNum) = CY_TCPWM_CNT_PERIOD_BUFF_DEFAULT;
370 TCPWM_CNT_TR_CTRL1(base, cntNum) = CY_TCPWM_CNT_TR_CTRL1_DEFAULT;
371 TCPWM_CNT_TR_CTRL2(base, cntNum) = CY_TCPWM_CNT_TR_CTRL2_DEFAULT;
372 TCPWM_CNT_INTR(base, cntNum) = CY_TCPWM_CNT_INTR_DEFAULT;
373 TCPWM_CNT_INTR_SET(base, cntNum) = CY_TCPWM_CNT_INTR_SET_DEFAULT;
374 TCPWM_CNT_INTR_MASK(base, cntNum) = CY_TCPWM_CNT_INTR_MASK_DEFAULT;
375
376 if (CY_TCPWM_INPUT_CREATOR != config->countInput)
377 {
378 TCPWM_CNT_TR_CTRL0(base, cntNum) = CY_TCPWM_CNT_TR_CTRL0_DEFAULT;
379 }
380 #else
381 (void)config;
382 uint32_t grp = TCPWM_GRP_CNT_GET_GRP(cntNum);
383 bool enabled_bit = _FLD2BOOL(TCPWM_GRP_CNT_V2_CTRL_ENABLED, TCPWM_GRP_CNT_CTRL(base, grp, cntNum));
384
385 TCPWM_GRP_CNT_CTRL(base, grp, cntNum) = (CY_TCPWM_GRP_CNT_CTRL_DEFAULT | (enabled_bit ? TCPWM_GRP_CNT_V2_CTRL_ENABLED_Msk : 0UL));
386 TCPWM_GRP_CNT_DT(base, grp, cntNum) = CY_TCPWM_GRP_CNT_DT_DEFAULT;
387 TCPWM_GRP_CNT_COUNTER(base, grp, cntNum) = CY_TCPWM_GRP_CNT_COUNTER_DEFAULT;
388 TCPWM_GRP_CNT_TR_PWM_CTRL(base, grp, cntNum) = CY_TCPWM_GRP_CNT_TR_PWM_CTRL_DEFAULT;
389 TCPWM_GRP_CNT_CC0(base, grp, cntNum) = CY_TCPWM_GRP_CNT_CC0_DEFAULT;
390 TCPWM_GRP_CNT_CC0_BUFF(base, grp, cntNum) = CY_TCPWM_GRP_CNT_CC0_BUFF_DEFAULT;
391 TCPWM_GRP_CNT_CC1(base, grp, cntNum) = CY_TCPWM_GRP_CNT_CC0_DEFAULT;
392 TCPWM_GRP_CNT_CC1_BUFF(base, grp, cntNum) = CY_TCPWM_GRP_CNT_CC0_BUFF_DEFAULT;
393 TCPWM_GRP_CNT_PERIOD(base, grp, cntNum) = CY_TCPWM_GRP_CNT_PERIOD_DEFAULT;
394 TCPWM_GRP_CNT_PERIOD_BUFF(base, grp, cntNum) = CY_TCPWM_GRP_CNT_PERIOD_BUFF_DEFAULT;
395 TCPWM_GRP_CNT_TR_IN_SEL0(base, grp, cntNum) = CY_TCPWM_GRP_CNT_TR_IN_SEL0_DEFAULT;
396 TCPWM_GRP_CNT_TR_IN_SEL1(base, grp, cntNum) = CY_TCPWM_GRP_CNT_TR_IN_SEL1_DEFAULT;
397 TCPWM_GRP_CNT_TR_IN_EDGE_SEL(base, grp, cntNum) = CY_TCPWM_GRP_CNT_TR_IN_EDGE_SEL_DEFAULT;
398 TCPWM_GRP_CNT_INTR_MASK(base, grp, cntNum) = CY_TCPWM_GRP_CNT_INTR_MASK_DEFAULT;
399 #endif
400 }
401
402 #if defined (CY_IP_MXS40TCPWM) || defined (CY_DOXYGEN)
403 /*******************************************************************************
404 * Function Name: Cy_TCPWM_PWM_Configure_Dithering
405 ****************************************************************************//**
406 *
407 * configures dithering. applicable only when GRP_DITHERING_PRESENT and in PWM and PWM_DT mode
408 *
409 * \param base
410 * The pointer to a TCPWM instance.
411 *
412 * \param cntNum
413 * The Counter instance number in the selected TCPWM.
414 *
415 * \param mode
416 * Dithering mode See \ref cy_en_tcpwm_dithering_t .
417 *
418 * \param period
419 * initial value for period LFSR. Should be non zero value.
420 *
421 * \param duty
422 * Initial value for duty LFSR. Should be non zero value.
423 *
424 * \param limiter
425 * Dithering limiter values. It defines the magnitude of the pseudo-random value to be added to period/CC0/CC1 \ref cy_en_dithering_limiter_t
426 *
427 * \return
428 * Error / Status code. See cy_en_tcpwm_status_t.
429 *
430 * \note When PWM alignment mode set to "asymmetric CC0 and CC1",
431 * The duty width remains the same, because the same value is added to CC0 and CC1. As LFSR is updated at tc event and both CC0 match and CC1 match happen before tc event.
432 *******************************************************************************/
Cy_TCPWM_PWM_Configure_Dithering(TCPWM_Type * base,uint32_t cntNum,cy_en_tcpwm_dithering_t mode,uint8_t period,uint8_t duty,cy_en_dithering_limiter_t limiter)433 cy_en_tcpwm_status_t Cy_TCPWM_PWM_Configure_Dithering(TCPWM_Type *base, uint32_t cntNum, cy_en_tcpwm_dithering_t mode, uint8_t period, uint8_t duty, cy_en_dithering_limiter_t limiter)
434 {
435 cy_en_tcpwm_status_t status = CY_TCPWM_SUCCESS;
436 uint32_t grp = TCPWM_GRP_CNT_GET_GRP(cntNum);
437 bool dithering_present = ((bool)TCPWM_GRP_DITHERING_PRESENT(grp));
438 if(dithering_present)
439 {
440 if((period == 0U) || (duty == 0U))
441 {
442 status = CY_TCPWM_BAD_PARAM;
443 }
444 TCPWM_GRP_CNT_CTRL(base, grp, cntNum) |= _VAL2FLD(TCPWM_GRP_CNT_V3_CTRL_DITHEREN, mode);
445 TCPWM_GRP_CNT_LFSR(base, grp, cntNum) = (_VAL2FLD(TCPWM_GRP_CNT_V3_LFSR_PLFSR, period) |
446 _VAL2FLD(TCPWM_GRP_CNT_V3_LFSR_DLFSR, duty) |
447 _VAL2FLD(TCPWM_GRP_CNT_V3_LFSR_LIMITER, limiter));
448 }
449 else
450 {
451 status = CY_TCPWM_BAD_PARAM;
452 }
453 return status;
454 }
455
456 #endif /* defined (CY_IP_MXS40TCPWM) */
457 #if defined(__cplusplus)
458 }
459 #endif
460
461 #endif /* CY_IP_MXTCPWM */
462
463 /* [] END OF FILE */
464