FuSa 8-Bit Libraries Safety Framework
Loading...
Searching...
No Matches
midware_clock_manager.c
Go to the documentation of this file.
1
22
23// Framework Includes
24#include <driver_clkctrl.h>
26
27// Device-specific Includes
28#include <xc.h>
29
30// Function prototypes
31static uint8_t DetermineDivRegVal(clkFrqDiv_t divVal);
32
34{
35 const uint8_t regVal = CLKCTRL_ReadIntFlags();
36 const uint8_t cfd0FlagMask = (uint8_t)CLKCTRL_CFD0_bm;
37 const bool isCfd0Error = ((regVal & cfd0FlagMask) == cfd0FlagMask);
38
39 errFlag_t flag = NO_ERROR;
40 if (isCfd0Error)
41 {
42 flag = ERROR;
43 CLKCTRL_WriteIntFlags(cfd0FlagMask); // The flag is cleared by writing the flag bitmask
44 }
45
46 return flag;
47}
48
50{
51 const uint8_t regVal = CLKCTRL_ReadIntFlags();
52 const uint8_t cfd1FlagMask = (uint8_t)CLKCTRL_CFD1_bm;
53 const bool isCfd1Error = ((regVal & cfd1FlagMask) == cfd1FlagMask);
54
55 errFlag_t flag = NO_ERROR;
56 if (isCfd1Error)
57 {
58 flag = ERROR;
59 CLKCTRL_WriteIntFlags(cfd1FlagMask); // The flag is cleared by writing the flag bitmask
60 }
61
62 return flag;
63}
64
66{
67 const uint8_t regVal = CLKCTRL_ReadIntFlags();
68 const uint8_t cfm0FlagMask = (uint8_t)CLKCTRL_CFM0_bm;
69 const bool isCfm0Error = ((regVal & cfm0FlagMask) == cfm0FlagMask);
70
71 errFlag_t flag = NO_ERROR;
72 if (isCfm0Error)
73 {
74 flag = ERROR;
75 CLKCTRL_WriteIntFlags(cfm0FlagMask); // The flag is cleared by writing the flag bitmask
76 }
77
78 return flag;
79}
80
82{
83 const uint8_t regVal = CLKCTRL_ReadIntFlags();
84 const uint8_t cfm1FlagMask = (uint8_t)CLKCTRL_CFM1_bm;
85 const bool isCfm1Error = ((regVal & cfm1FlagMask) == cfm1FlagMask);
86
87 errFlag_t flag = NO_ERROR;
88 if (isCfm1Error)
89 {
90 flag = ERROR;
91 CLKCTRL_WriteIntFlags(cfm1FlagMask); // The flag is cleared by writing the flag bitmask
92 }
93
94 return flag;
95}
96
98{
99 const uint8_t cfmd0FlagMask = (uint8_t)CLKCTRL_CFMD0_bm;
100 const uint8_t cfmd1FlagMask = (uint8_t)CLKCTRL_CFMD1_bm;
101 CLKCTRL_WriteIntFlags(cfmd0FlagMask | cfmd1FlagMask); // Clear flags by writing flags bitmask
102}
103
105{
106 // Check for invalid inputs
107 const bool invalidDiv = (divider == CLK_FRQ_DIV_INVALID1) || (divider == CLK_FRQ_DIV_INVALID2);
108 const bool invalidFrq = (frequency == CLK_FRQ_INVALID);
109 const bool outOfRange = (divider >= CLK_FRQ_DIV_MAX) || (frequency >= CLK_FRQ_MAX);
110
111 if (invalidDiv || invalidFrq || outOfRange)
112 {
113 /* cppcheck-suppress misra-c2012-15.5 */
114 return ERROR;
115 }
116
117 // Set FRQSEL config without changing of RUNSTDBY and AUTOTUNE settings
118 const uint8_t frequencySelMask = (uint8_t)CLKCTRL_FRQSEL_gm;
119 const uint8_t frequencyConfig = ((uint8_t)frequency << CLKCTRL_FRQSEL_gp);
120 CLKCTRL_ModifyOscHfControlA(frequencySelMask, frequencyConfig);
121
122 // Set OSCHF as clock source
123 const uint8_t clockSelMask = (uint8_t)CLKCTRL_CLKSEL_gm;
124 const uint8_t clockSelConfig = ((uint8_t)CLKCTRL_CLKSEL_OSCHF_gc);
125 CLKCTRL_ModifyMainControlA(clockSelMask, clockSelConfig);
126
127 // Set clock division
128 const uint8_t regVal = DetermineDivRegVal(divider);
130
131 return NO_ERROR;
132}
133
135{
136 // Check for invalid inputs
137 const bool outOfRange = (src >= CFD_SRC_MAX) || (ref >= CFD_REF_MAX);
138
139 if (outOfRange)
140 {
141 /* cppcheck-suppress misra-c2012-15.5 */
142 return ERROR;
143 }
144
145 // Assemble register value
146 const uint8_t clockSource = (uint8_t)src << (uint8_t)CLKCTRL_CFDSRC_gp;
147 const uint8_t clockReference = (uint8_t)ref << (uint8_t)CLKCTRL_CFDREF_gp;
148 const uint8_t cfdEnable = (uint8_t)CLKCTRL_CFDEN_bm;
149 const uint8_t regVal = (clockSource | clockReference | cfdEnable);
150
151 // Set CFD configuration
153
154 return NO_ERROR;
155}
156
158{
159 // Check for invalid inputs
160 const bool outOfRange = (src >= CFD_SRC_MAX) || (ref >= CFD_REF_MAX);
161
162 if (outOfRange)
163 {
164 /* cppcheck-suppress misra-c2012-15.5 */
165 return ERROR;
166 }
167
168 // Assemble register value
169 const uint8_t clockSource = (uint8_t)src << (uint8_t)CLKCTRL_CFDSRC_gp;
170 const uint8_t clockReference = (uint8_t)ref << (uint8_t)CLKCTRL_CFDREF_gp;
171 const uint8_t cfdEnable = (uint8_t)CLKCTRL_CFDEN_bm;
172 const uint8_t regVal = (clockSource | clockReference | cfdEnable);
173
174 // Set CFD configuration
176
177 return NO_ERROR;
178}
179
180errFlag_t MW_StartCfm0(cfmSource_t src, cfmReference_t ref, cfmWindow_t window, bool useContinuous)
181{
182 // Check for invalid inputs
183 const bool outOfRange = (src >= CFM_SRC_MAX) || (ref >= CFM_REF_MAX);
184
185 if (outOfRange)
186 {
187 /* cppcheck-suppress misra-c2012-15.5 */
188 return ERROR;
189 }
190
191 // Assemble register value for source
192 uint8_t type = (uint8_t)CLKCTRL_TYPE_ONESHOT_gc;
193 if (useContinuous)
194 {
195 type = (uint8_t)CLKCTRL_TYPE_CONTINUOUS_gc;
196 }
197
198 // Configure window parameters
202
203 const uint8_t refEnableMask = (uint8_t)CLKCTRL_REFCEN_bm;
204 const uint8_t referenceConfig = (uint8_t)ref << CLKCTRL_CFMREF_gp;
205 const uint8_t regValRef = (referenceConfig | refEnableMask);
206 CLKCTRL_WriteCfm0ControlB(regValRef);
207
208 const uint8_t cfmEnableMask = (uint8_t)CLKCTRL_MEN_bm;
209 const uint8_t sourceConfig = (uint8_t)src << CLKCTRL_CFMSRC_gp;
210 const uint8_t regValSrc = (type | sourceConfig | cfmEnableMask);
211 CLKCTRL_WriteCfm0ControlA(regValSrc);
212
213 return NO_ERROR;
214}
215
216errFlag_t MW_StartCfm1(cfmSource_t src, cfmReference_t ref, cfmWindow_t window, bool useContinuous)
217{
218 // Check for invalid inputs
219 const bool outOfRange = (src >= CFM_SRC_MAX) || (ref >= CFM_REF_MAX);
220
221 if (outOfRange)
222 {
223 /* cppcheck-suppress misra-c2012-15.5 */
224 return ERROR;
225 }
226
227 // Assemble register value for source
228 uint8_t type = (uint8_t)CLKCTRL_TYPE_ONESHOT_gc;
229 if (useContinuous)
230 {
231 type = (uint8_t)CLKCTRL_TYPE_CONTINUOUS_gc;
232 }
233
234 // Configure window parameters
238
239 const uint8_t refEnableMask = (uint8_t)CLKCTRL_REFCEN_bm;
240 const uint8_t referenceConfig = (uint8_t)ref << CLKCTRL_CFMREF_gp;
241 const uint8_t regValRef = (referenceConfig | refEnableMask);
242 CLKCTRL_WriteCfm1ControlB(regValRef);
243
244 const uint8_t cfmEnableMask = (uint8_t)CLKCTRL_MEN_bm;
245 const uint8_t sourceConfig = (uint8_t)src << CLKCTRL_CFMSRC_gp;
246 const uint8_t regValSrc = (type | sourceConfig | cfmEnableMask);
247 CLKCTRL_WriteCfm1ControlA(regValSrc);
248
249 return NO_ERROR;
250}
251
253{
254 const uint8_t cfdErrorMask = (uint8_t)CLKCTRL_CFD0_bm | (uint8_t)CLKCTRL_CFD1_bm;
255 const uint8_t cfmErrorMask = (uint8_t)CLKCTRL_CFM0_bm | (uint8_t)CLKCTRL_CFM1_bm;
256
257 CLKCTRL_WriteIntControl(cfdErrorMask | cfmErrorMask);
258}
259
260static uint8_t DetermineDivRegVal(clkFrqDiv_t divVal)
261{
262 // Disable prescaler division by default
263 const uint8_t divDisableMask = 0U << CLKCTRL_PEN_bp;
264 const uint8_t defaultDivConfig = (uint8_t)CLKCTRL_PDIV_DIV2_gc;
265 uint8_t regVal = defaultDivConfig | divDisableMask;
266
267 if (divVal != CLK_FRQ_DIV_OFF)
268 {
269 const uint8_t divConfig = ((uint8_t)divVal << CLKCTRL_PDIV_gp);
270 const uint8_t divEnableMask = (uint8_t)CLKCTRL_PEN_bm;
271 regVal = divConfig | divEnableMask;
272 }
273
274 return regVal;
275}
errFlag_t
Defines the error flag used by Middleware services to indicate error detection.
@ NO_ERROR
void CLKCTRL_WriteCfm1ControlA(uint8_t value)
Overwrites the MCLKCFM1CTRLA register value.
void CLKCTRL_WriteCfd0ControlA(uint8_t value)
Overwrites the MCLKCFD0CTRLA register value.
void CLKCTRL_WriteIntControl(uint8_t value)
Overwrites the MCLKINTCTRL register value.
void CLKCTRL_WriteCfm1WindowHigh(uint16_t value)
Overwrites the MCLKCFM1WINHT register value.
void CLKCTRL_WriteCfm0ControlB(uint8_t value)
Overwrites the MCLKCFM0CTRLB register value.
void CLKCTRL_WriteCfm1WindowLow(uint16_t value)
Overwrites the MCLKCFM1WINLT register value.
void CLKCTRL_WriteCfm1RefNum(uint16_t value)
Overwrites the MCLKCFM1REFNUM register value.
void CLKCTRL_WriteMainControlB(uint8_t value)
Overwrites the MCLKCTRLB register value.
void CLKCTRL_ModifyOscHfControlA(uint8_t groupMask, uint8_t groupConfig)
Modifies specific bit field(s) in the OSCHFCTRLA register.
void CLKCTRL_WriteCfd1ControlA(uint8_t value)
Overwrites the MCLKCFD1CTRLA register value.
void CLKCTRL_WriteCfm0RefNum(uint16_t value)
Overwrites the MCLKCFM0REFNUM register value.
void CLKCTRL_WriteCfm0WindowHigh(uint16_t value)
Overwrites the MCLKCFM0WINHT register value.
void CLKCTRL_WriteCfm1ControlB(uint8_t value)
Overwrites the MCLKCFM1CTRLB register value.
uint8_t CLKCTRL_ReadIntFlags(void)
Reads the MCLKINTFLAGS register value.
void CLKCTRL_ModifyMainControlA(uint8_t groupMask, uint8_t groupConfig)
Modifies specific bit field(s) in the MCLKCTRLA register.
void CLKCTRL_WriteCfm0WindowLow(uint16_t value)
Overwrites the MCLKCFM0WINLT register value.
void CLKCTRL_WriteCfm0ControlA(uint8_t value)
Overwrites the MCLKCFM0CTRLA register value.
void CLKCTRL_WriteIntFlags(uint8_t value)
Overwrites the MCLKINTFLAGS register value.
cfmReference_t
Type definitions for available Clock Frequency Measure (CFM) references used for configuring the CFMs...
errFlag_t MW_GetClearClockCfd0Error(void)
Reads and clears the flag indicating a clock failure detected by CFD0.
cfdSource_t
Type definitions for available Clock Failure Detection (CFD) sources used for configuring the CFDs.
void MW_EnableClockInterrupts(void)
Enables all Clock Failure Detect (CFD) and Clock Frequency Measure (CFM) interrupts.
clkFrq_t
Type definitions for available High Frequency Oscillator output frequencies used for configuring the ...
cfdReference_t
Type definitions for available Clock Failure Detection (CFD) references used for configuring the CFDs...
errFlag_t MW_StartCfd1(cfdSource_t src, cfdReference_t ref)
Starts Clock Failure Detect 1 (CFD1) to monitor the configured clock source with the configured refer...
clkFrqDiv_t
Type definitions for available pre-scaler division used for configuring the main clock.
cfmSource_t
Type definitions for available Clock Frequency Measure (CFM) sources used for configuring the CFMs.
errFlag_t MW_StartCfm0(cfmSource_t src, cfmReference_t ref, cfmWindow_t window, bool useContinuous)
Starts continuous Clock Frequency Measure 0 (CFM0) to monitor the configured clock source with the co...
errFlag_t MW_GetClearClockCfm1Error(void)
Reads and clears the flag indicating a clock frequency error measured by CFM1.
errFlag_t MW_StartCfm1(cfmSource_t src, cfmReference_t ref, cfmWindow_t window, bool useContinuous)
Starts continuous Clock Frequency Measure 1 (CFM1) to monitor the configured clock source with the co...
errFlag_t MW_StartCfd0(cfdSource_t src, cfdReference_t ref)
Starts Clock Failure Detect 0 (CFD0) to monitor the configured clock source with the configured refer...
errFlag_t MW_SetMainClockFrequency(clkFrq_t frequency, clkFrqDiv_t divider)
Initializes main clock with internal High Frequency Oscillator (OSCHF) as clock source.
void MW_ClearClockCfmDoneFlags(void)
Clears the Clock Frequency Measure Done (CFMDn) flags indicating that a clock frequency measurement i...
errFlag_t MW_GetClearClockCfd1Error(void)
Reads and clears the flag indicating a clock failure detected by CFD1.
errFlag_t MW_GetClearClockCfm0Error(void)
Reads and clears the flag indicating a clock frequency error measured by CFM0.
@ CLK_FRQ_INVALID
@ CLK_FRQ_DIV_INVALID2
@ CLK_FRQ_DIV_MAX
@ CLK_FRQ_DIV_INVALID1
@ CLK_FRQ_DIV_OFF
Struct for configuring the Clock Frequency Measure window.