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