1 /***************************************************************************//**
2 * \file cy_evtgen.c
3 * \version 1.0
4 *
5 * \brief
6 * Provides API implementation of the Event generator Driver.
7 *
8 ********************************************************************************
9 * \copyright
10 * Copyright 2016-2022 Cypress Semiconductor Corporation. All rights reserved.
11 * You may use this file only in accordance with the license, terms, conditions,
12 * disclaimers, and limitations in the end user license agreement accompanying
13 * the software package with which this file was provided.
14 *******************************************************************************/
15
16 #include "cy_evtgen.h"
17
18 #ifdef CY_IP_MXEVTGEN
19
20 #define RATIO_FRAC_SHIFT 100UL /* This value is required to shift the fractional comma by two characters.
21 It needs for the selection fractional part ratio. */
22
23 /*******************************************************************************
24 * Function Name: Cy_EvtGen_RatioCalculate
25 ****************************************************************************//**
26 *
27 * Internal function for calculate two part of the RATIO register.
28 *
29 * \param frequencyTick
30 * High frequency of the Event Generator.
31 *
32 * \param frequencyLf
33 * Low frequency of the Event Generator.
34 *
35 * \param ratioInt
36 * The pointer to a variable where the integer part is stored.
37 *
38 * \param ratioFrac
39 * The pointer to a variable where the fractional part is stored.
40 *
41 *******************************************************************************/
Cy_EvtGen_RatioCalculate(uint32_t frequencyTick,uint32_t frequencyLf,uint16_t * ratioInt,uint8_t * ratioFrac)42 static void Cy_EvtGen_RatioCalculate(uint32_t frequencyTick, uint32_t frequencyLf, uint16_t* ratioInt, uint8_t* ratioFrac)
43 {
44 uint32_t tempInt = 0;
45 float tempFrac = (float)frequencyTick / (float)frequencyLf;
46
47 tempInt = (uint32_t)tempFrac;
48 tempFrac = tempFrac - (float)tempInt;
49 tempFrac = (tempFrac * (float)RATIO_FRAC_SHIFT);
50
51 *ratioFrac = (uint8_t)tempFrac;
52 *ratioInt = (uint16_t)tempInt;
53 }
54
55 /*******************************************************************************
56 * Function Name: Cy_EvtGen_Init
57 ****************************************************************************//**
58 *
59 * Initialize the event generator
60 *
61 * \param base
62 * Pointer to structure describing registers
63 *
64 * \param config
65 * Pointer to the event generator config structure base address
66 *
67 * \return
68 * Event generator initialization status
69 *
70 *******************************************************************************/
Cy_EvtGen_Init(EVTGEN_Type * base,const cy_stc_evtgen_config_t * config)71 cy_en_evtgen_status_t Cy_EvtGen_Init(EVTGEN_Type *base, const cy_stc_evtgen_config_t* config)
72 {
73 cy_en_evtgen_status_t ret = CY_EVTGEN_BAD_PARAM;
74
75 /* Checking input parameter valid */
76 if ((NULL != base) && (NULL != config))
77 {
78 if ((config->frequencyRef != 0UL) && (config->frequencyTick != 0UL))
79 {
80 uint32_t refDiv;
81
82 /* Setting divider value of clk_ref */
83 refDiv = config->frequencyRef / config->frequencyTick;
84
85 CY_ASSERT_L1(CY_EVTGEN_IS_DIVIDER_VALID_RANGE(refDiv));
86
87 if(((config->frequencyRef % config->frequencyTick) == 0UL) && ((refDiv <= 256UL) && (refDiv > 0UL)))
88 {
89 CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 10.8','Intentional typecast to uint8_t.');
90 base->REF_CLOCK_CTL = _VAL2FLD(EVTGEN_REF_CLOCK_CTL_INT_DIV, (uint8_t)(refDiv - 1UL));
91
92 /* Setting ratio operation */
93 if(config->ratioControlMode == CY_EVTGEN_RATIO_CONTROL_SW)
94 {
95 /* SW control: setting value for ratio value should be ratio between tick_ref_div and clk_lf. */
96 uint8_t ratioFrac;
97 uint16_t ratioInt;
98 Cy_EvtGen_RatioCalculate(config->frequencyTick, config->frequencyLf, &ratioInt, &ratioFrac);
99
100 base->RATIO = (_VAL2FLD(EVTGEN_RATIO_FRAC8, ratioFrac)) | (_VAL2FLD(EVTGEN_RATIO_INT16, ratioInt));
101
102 /* SW control: valid bit should be set manually. */
103 base->RATIO_CTL &= ~EVTGEN_RATIO_CTL_DYNAMIC_Msk;
104 base->RATIO_CTL |= EVTGEN_RATIO_CTL_VALID_Msk;
105 }
106 else
107 {
108 /* HW control: */
109 base->RATIO_CTL |= EVTGEN_RATIO_CTL_DYNAMIC_Msk |
110 (_VAL2FLD(EVTGEN_RATIO_CTL_DYNAMIC_MODE, config->ratioValueDynamicMode));
111 }
112 ret = CY_EVTGEN_SUCCESS;
113 }
114 }
115 }
116 return (ret);
117 }
118
119 /*******************************************************************************
120 * Function Name: Cy_EvtGen_DeInit
121 ****************************************************************************//**
122 *
123 * Deinitialize event generator
124 *
125 * \param base
126 * Pointer to structure describing registers
127 *
128 *******************************************************************************/
Cy_EvtGen_DeInit(EVTGEN_Type * base)129 void Cy_EvtGen_DeInit(EVTGEN_Type *base)
130 {
131 CY_ASSERT_L1(base);
132
133 /* Returns block registers into the default state */
134 base->CTL = 0UL;
135 base->REF_CLOCK_CTL = 0UL;
136 base->RATIO = 0UL;
137 base->RATIO_CTL = 0UL;
138 base->INTR_MASK = 0UL;
139 base->INTR_DPSLP_MASK = 0UL;
140 }
141
142 /*******************************************************************************
143 * Function Name: Cy_EvtGen_InitStruct
144 ****************************************************************************//**
145 *
146 * Initialize a comparator structure
147 *
148 * \param base
149 * Pointer to structure describing registers
150 *
151 * \param structNum
152 * Number of structure to be initialized. Valid range from 0 to 16.
153 *
154 * \param configStruct
155 * Pointer to the event generator structure config structure base address
156 *
157 * \return
158 * Event generator initialization status
159 *
160 *******************************************************************************/
Cy_EvtGen_InitStruct(EVTGEN_Type * base,uint8_t structNum,const cy_stc_evtgen_struct_config_t * configStruct)161 cy_en_evtgen_status_t Cy_EvtGen_InitStruct(EVTGEN_Type *base,
162 uint8_t structNum,
163 const cy_stc_evtgen_struct_config_t* configStruct)
164 {
165 cy_en_evtgen_status_t ret = CY_EVTGEN_BAD_PARAM;
166
167 /* Checking input parameter valid */
168 if ((NULL != base) && (NULL != configStruct) && (EVTGEN_COMP_STRUCT_NR > structNum))
169 {
170 uint64_t tempCounterValue = 0UL;
171 uint32_t tempCompStructCompCTL = 0UL;
172
173 tempCompStructCompCTL = base->COMP_STRUCT[structNum].COMP_CTL;
174
175 if (CY_EVTGEN_DEEPSLEEP_FUNCTIONALITY == configStruct->functionalitySelection)
176 {
177 tempCompStructCompCTL |= EVTGEN_COMP_STRUCT_COMP_CTL_COMP1_EN_Msk;
178 }
179
180 tempCompStructCompCTL |= EVTGEN_COMP_STRUCT_COMP_CTL_COMP0_EN_Msk |
181 (_VAL2FLD(EVTGEN_COMP_STRUCT_COMP_CTL_TR_OUT_EDGE, configStruct->triggerOutEdge)) |
182 EVTGEN_COMP_STRUCT_COMP_CTL_ENABLED_Msk;
183
184 CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 10.8','Intentional typecast to uint64_t.');
185 tempCounterValue = (uint64_t) (_FLD2VAL(EVTGEN_COUNTER_INT32, base->COUNTER));
186
187 /* Setting active comparator value */
188 base->COMP_STRUCT[structNum].COMP0 = (uint32_t) (tempCounterValue + (uint64_t) configStruct->valueActiveComparator);
189
190 /* Setting deep sleep comparator value */
191 if (CY_EVTGEN_DEEPSLEEP_FUNCTIONALITY == configStruct->functionalitySelection)
192 {
193 base->COMP_STRUCT[structNum].COMP1 = (uint32_t)(tempCounterValue + (uint64_t)configStruct->valueDeepSleepComparator);
194 }
195
196 /* Setting comparator struct control parameter */
197 base->COMP_STRUCT[structNum].COMP_CTL = tempCompStructCompCTL;
198
199 Cy_EvtGen_SetStructInterruptMask(base, structNum);
200 if (CY_EVTGEN_DEEPSLEEP_FUNCTIONALITY == configStruct->functionalitySelection)
201 {
202 Cy_EvtGen_SetStructInterruptDeepSleepMask(base, structNum);
203 }
204
205 ret = CY_EVTGEN_SUCCESS;
206 }
207 return (ret);
208 }
209
210 /*******************************************************************************
211 * Function Name: Cy_EvtGen_DeinitStruct
212 ****************************************************************************//**
213 *
214 * Deinitialize event generator struct
215 *
216 * \param base
217 * Pointer to structure describing registers
218 *
219 * \param structNum
220 * Number of structure to be de-initialized. Valid range from 0 to 16.
221 *
222 *******************************************************************************/
Cy_EvtGen_DeinitStruct(EVTGEN_Type * base,uint8_t structNum)223 void Cy_EvtGen_DeinitStruct(EVTGEN_Type *base, uint8_t structNum)
224 {
225 CY_ASSERT_L1(CY_EVTGEN_IS_BASE_VALID(base));
226 CY_ASSERT_L1(CY_EVTGEN_IS_STRUCTNUM_VALID(structNum));
227
228 base->COMP_STRUCT[structNum].COMP_CTL = 0UL;
229 base->COMP_STRUCT[structNum].COMP0 = 0UL;
230 base->COMP_STRUCT[structNum].COMP1 = 0UL;
231 }
232
233 /*******************************************************************************
234 * Function Name: Cy_EvtGen_UpdateActiveCompValue
235 ****************************************************************************//**
236 *
237 * Update active comparator value corresponding comparator structure.
238 *
239 * \param base
240 * Pointer to structure describing registers
241 *
242 * \param structNum
243 * Number of structure to be update value. Valid range from 0 to 15.
244 *
245 * \param newCompareValue
246 * Value for update active comparator value.
247 *
248 *******************************************************************************/
Cy_EvtGen_UpdateActiveCompValue(EVTGEN_Type * base,uint8_t structNum,uint32_t newCompareValue)249 void Cy_EvtGen_UpdateActiveCompValue(EVTGEN_Type *base, uint8_t structNum, uint32_t newCompareValue)
250 {
251 CY_ASSERT_L1(CY_EVTGEN_IS_STRUCTNUM_VALID(structNum));
252
253 /* Note: In cases where the current value of the comparator is close to MAX_INT
254 then the update may lead to overflow. Using 64 bit handles this case. Cast to
255 32 bit is safe brings the value to what it will be after the counter overflows. */
256 uint64_t tempCompValue = (uint64_t) EVTGEN0->COMP_STRUCT[structNum].COMP0;
257 tempCompValue += newCompareValue;
258
259 base->COMP_STRUCT[structNum].COMP_CTL &= ~EVTGEN_COMP_STRUCT_COMP_CTL_COMP0_EN_Msk;
260 base->COMP_STRUCT[structNum].COMP0 = (uint32_t) tempCompValue;
261 base->COMP_STRUCT[structNum].COMP_CTL |= EVTGEN_COMP_STRUCT_COMP_CTL_COMP0_EN_Msk;
262 }
263
264 /*******************************************************************************
265 * Function Name: Cy_EvtGen_UpdateDeepSleepCompValue
266 ****************************************************************************//**
267 *
268 * Update Deep Sleep comparator value corresponding comparator structure.
269 *
270 * \param base
271 * Pointer to structure describing registers
272 *
273 * \param structNum
274 * Number of structure to be update value. Valid range from 0 to 15.
275 *
276 * \param newCompareValue
277 * Value for update Deep Sleep comparator value.
278 *
279 *******************************************************************************/
Cy_EvtGen_UpdateDeepSleepCompValue(EVTGEN_Type * base,uint8_t structNum,uint32_t newCompareValue)280 void Cy_EvtGen_UpdateDeepSleepCompValue(EVTGEN_Type *base, uint8_t structNum, uint32_t newCompareValue)
281 {
282 CY_ASSERT_L1(CY_EVTGEN_IS_STRUCTNUM_VALID(structNum));
283
284 /* Note: In cases where the current value of the comparator is close to MAX_INT
285 then the update may lead to overflow. Using 64 bit handles this case. Cast to
286 32 bit is safe brings the value to what it will be after the counter overflows. */
287 uint64_t tempCompValue = (uint64_t) EVTGEN0->COMP_STRUCT[structNum].COMP1;
288 tempCompValue += newCompareValue;
289
290 base->COMP_STRUCT[structNum].COMP_CTL &= ~EVTGEN_COMP_STRUCT_COMP_CTL_COMP1_EN_Msk;
291 base->COMP_STRUCT[structNum].COMP1 = (uint32_t) tempCompValue;
292 base->COMP_STRUCT[structNum].COMP_CTL |= EVTGEN_COMP_STRUCT_COMP_CTL_COMP1_EN_Msk;
293 }
294
295 #endif /* CY_IP_MXEVTGEN */
296
297 /* [] END OF FILE */
298