]> rtime.felk.cvut.cz Git - arc.git/blob - arch/arm/arm_cm3/drivers/Mcu.c
Fixed erronous filenames in includes.
[arc.git] / arch / arm / arm_cm3 / drivers / Mcu.c
1 /* -------------------------------- Arctic Core ------------------------------\r
2  * Arctic Core - the open source AUTOSAR platform http://arccore.com\r
3  *\r
4  * Copyright (C) 2009  ArcCore AB <contact@arccore.com>\r
5  *\r
6  * This source code is free software; you can redistribute it and/or modify it\r
7  * under the terms of the GNU General Public License version 2 as published by the\r
8  * Free Software Foundation; See <http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt>.\r
9  *\r
10  * This program is distributed in the hope that it will be useful, but\r
11  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
12  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\r
13  * for more details.\r
14  * -------------------------------- Arctic Core ------------------------------*/\r
15 \r
16 \r
17 #include "Std_Types.h"\r
18 #include "Mcu.h"\r
19 #include "Det.h"\r
20 #if defined(USE_DEM)\r
21 #include "Dem.h"\r
22 #endif\r
23 #include <assert.h>\r
24 #include "Cpu.h"\r
25 #include <string.h>\r
26 #include "Ramlog.h"\r
27 \r
28 //#define USE_TRACE 1\r
29 //#define USE_LDEBUG_PRINTF 1\r
30 #include "debug.h"\r
31 \r
32 \r
33 #ifndef ARRAY_SIZE\r
34 #define ARRAY_SIZE(_x)  (sizeof(_x)/sizeof((_x)[0]))\r
35 #endif\r
36 \r
37 /* Development error macros. */\r
38 #if ( MCU_DEV_ERROR_DETECT == STD_ON )\r
39 #define VALIDATE(_exp,_api,_err ) \\r
40         if( !(_exp) ) { \\r
41           Det_ReportError(MODULE_ID_MCU,0,_api,_err); \\r
42           return; \\r
43         }\r
44 \r
45 #define VALIDATE_W_RV(_exp,_api,_err,_rv ) \\r
46         if( !(_exp) ) { \\r
47           Det_ReportError(MODULE_ID_MCU,0,_api,_err); \\r
48           return (_rv); \\r
49         }\r
50 #else\r
51 #define VALIDATE(_exp,_api,_err )\r
52 #define VALIDATE_W_RV(_exp,_api,_err,_rv )\r
53 #endif\r
54 \r
55 \r
56 #define CORE_CPUID_CORTEX_M3    0x411FC231UL\r
57 \r
58 \r
59 \r
60 typedef struct {\r
61         uint32 lossOfLockCnt;\r
62         uint32 lossOfClockCnt;\r
63 } Mcu_Stats;\r
64 \r
65 /**\r
66  * Type that holds all global data for Mcu\r
67  */\r
68 typedef struct\r
69 {\r
70   // Set if Mcu_Init() have been called\r
71   boolean initRun;\r
72 \r
73   // Our config\r
74   const Mcu_ConfigType *config;\r
75 \r
76   Mcu_ClockType clockSetting;\r
77 \r
78   Mcu_Stats stats;\r
79 \r
80 } Mcu_GlobalType;\r
81 \r
82 \r
83 // Global config\r
84 Mcu_GlobalType Mcu_Global =\r
85 {\r
86                 .initRun = 0,\r
87                 .config = &McuConfigData[0],\r
88 };\r
89 \r
90 //-------------------------------------------------------------------\r
91 \r
92 typedef struct {\r
93   char *name;\r
94   uint32 pvr;\r
95 } core_info_t;\r
96 \r
97 typedef struct {\r
98   char *name;\r
99   uint32 pvr;\r
100 } cpu_info_t;\r
101 \r
102 \r
103 void Mcu_ConfigureFlash(void);\r
104 \r
105 \r
106 \r
107 /* Haven't found any ID accessable from memory.\r
108  * There is the DBGMCU_IDCODE (0xe0042000) found in RM0041 but it\r
109  * you can't read from that address..\r
110  */\r
111 #if 0\r
112 cpu_info_t cpu_info_list[] = {\r
113     {\r
114     .name = "????",\r
115     .pvr = 0,\r
116     },\r
117 };\r
118 #endif\r
119 \r
120 /* The supported cores\r
121  */\r
122 core_info_t core_info_list[] = {\r
123     {\r
124     .name = "CORE_ARM_CORTEX_M3",\r
125     .pvr = CORE_CPUID_CORTEX_M3,\r
126     },\r
127 };\r
128 \r
129 #if 0\r
130 static cpu_info_t *Mcu_IdentifyCpu(uint32 pvr)\r
131 {\r
132   int i;\r
133   for (i = 0; i < ARRAY_SIZE(cpu_info_list); i++) {\r
134     if (cpu_info_list[i].pvr == pvr) {\r
135       return &cpu_info_list[i];\r
136     }\r
137   }\r
138 \r
139   return NULL;\r
140 }\r
141 #endif\r
142 \r
143 \r
144 static core_info_t *Mcu_IdentifyCore(uint32 pvr)\r
145 {\r
146   int i;\r
147   for (i = 0; i < ARRAY_SIZE(core_info_list); i++) {\r
148     if (core_info_list[i].pvr == pvr) {\r
149       return &core_info_list[i];\r
150     }\r
151   }\r
152 \r
153   return NULL;\r
154 }\r
155 \r
156 /**\r
157  * Identify the core, just to check that we have support for it.\r
158  *\r
159  * @return\r
160  */\r
161 static uint32 Mcu_CheckCpu( void ) {\r
162 \r
163   uint32 pvr = SCB->CPUID;\r
164   //uint32 pir;\r
165   //cpu_info_t *cpuType;\r
166   core_info_t *coreType;\r
167 \r
168   //cpuType = Mcu_IdentifyCpu(pvr);\r
169   coreType = Mcu_IdentifyCore(pvr);\r
170 \r
171   if( (coreType == NULL) ) {\r
172     // Just hang\r
173     while(1);\r
174   }\r
175 \r
176   return 0;\r
177 }\r
178 \r
179 static uint32_t GetPllValueFromMult(uint8_t pll)\r
180 {\r
181         return (((uint32_t)pll - 2) << 18);\r
182 }\r
183 static uint32_t GetPll2ValueFromMult(uint8_t pll)\r
184 {\r
185         return (((uint32_t)pll - 2) << 8);\r
186 }\r
187 \r
188 /**\r
189   * Set bus clocks. SysClk,AHBClk,APB1Clk,APB2Clk\r
190   */\r
191 static void SetClocks(Mcu_ClockSettingConfigType *clockSettingsPtr)\r
192 {\r
193   volatile uint32 StartUpCounter = 0, HSEStatus = 0;\r
194 \r
195   /* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/\r
196   /* Enable HSE */\r
197   RCC->CR |= ((uint32_t)RCC_CR_HSEON);\r
198 \r
199   /* Wait till HSE is ready and if Time out is reached exit */\r
200   do\r
201   {\r
202     HSEStatus = RCC->CR & RCC_CR_HSERDY;\r
203     StartUpCounter++;\r
204   } while((HSEStatus == 0) && (StartUpCounter != HSEStartUp_TimeOut));\r
205 \r
206   if ((RCC->CR & RCC_CR_HSERDY) != RESET)\r
207   {\r
208     HSEStatus = (uint32_t)0x01;\r
209   }\r
210   else\r
211   {\r
212     HSEStatus = (uint32_t)0x00;\r
213   }\r
214 \r
215   if (HSEStatus == (uint32_t)0x01)\r
216   {\r
217     /* Enable Prefetch Buffer */\r
218     FLASH->ACR |= FLASH_ACR_PRFTBE;\r
219 \r
220     /* Flash 2 wait state */\r
221     FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);\r
222     FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;\r
223 \r
224 \r
225     /* HCLK = SYSCLK */\r
226     RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;\r
227 \r
228     /* PCLK2 = HCLK */\r
229     RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;\r
230 \r
231     /* PCLK1 = HCLK */\r
232     RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;\r
233 \r
234 #ifdef STM32F10X_CL\r
235     /* Configure PLLs ------------------------------------------------------*/\r
236     /* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */\r
237     /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */\r
238 \r
239     RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL |\r
240                               RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC);\r
241     RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | GetPll2ValueFromMult(clockSettingsPtr->Pll2) |\r
242                              RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5);\r
243 \r
244     /* Enable PLL2 */\r
245     RCC->CR |= RCC_CR_PLL2ON;\r
246     /* Wait till PLL2 is ready */\r
247     while((RCC->CR & RCC_CR_PLL2RDY) == 0)\r
248     {\r
249     }\r
250 \r
251     /* PLL configuration: PLLCLK = PREDIV1 * 9 = 72 MHz */\r
252     RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL);\r
253     RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 |\r
254                                 GetPllValueFromMult(clockSettingsPtr->Pll1));\r
255 #else\r
256     /*  PLL configuration: PLLCLK = HSE * 9 = 72 MHz */\r
257     RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE |\r
258                                         RCC_CFGR_PLLMULL));\r
259     RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | GetPllValueFromMult(clockSettingsPtr->Pll1));\r
260 #endif /* STM32F10X_CL */\r
261 \r
262     /* Enable PLL */\r
263     RCC->CR |= RCC_CR_PLLON;\r
264 \r
265     /* Wait till PLL is ready */\r
266     while((RCC->CR & RCC_CR_PLLRDY) == 0)\r
267     {\r
268     }\r
269 \r
270     /* Select PLL as system clock source */\r
271     RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));\r
272     RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;\r
273 \r
274     /* Wait till PLL is used as system clock source */\r
275     while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)\r
276     {\r
277     }\r
278   }\r
279   else\r
280   { /* HSE fails to start-up, the application will have wrong clock */\r
281           NVIC_SystemReset();\r
282   }\r
283 }\r
284 \r
285 /**\r
286   * Initialize Peripherals clocks\r
287   */\r
288 static void InitPerClocks()\r
289 {\r
290         RCC->AHBENR |= McuPerClockConfigData.AHBClocksEnable;\r
291         RCC->APB1ENR |= McuPerClockConfigData.APB1ClocksEnable;\r
292         RCC->APB2ENR |= McuPerClockConfigData.APB2ClocksEnable;\r
293 }\r
294 \r
295 /**\r
296   * Initialize Flash, PLL and clocks.\r
297   */\r
298 static void InitMcuClocks(Mcu_ClockSettingConfigType *clockSettingsPtr)\r
299 {\r
300   /* Reset the RCC clock configuration to the default reset state(for debug purpose) */\r
301   /* Set HSION bit */\r
302   RCC->CR |= (uint32_t)0x00000001;\r
303 \r
304   /* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */\r
305 #ifndef STM32F10X_CL\r
306   RCC->CFGR &= (uint32_t)0xF8FF0000;\r
307 #else\r
308   RCC->CFGR &= (uint32_t)0xF0FF0000;\r
309 #endif /* STM32F10X_CL */\r
310 \r
311   /* Reset HSEON, CSSON and PLLON bits */\r
312   RCC->CR &= (uint32_t)0xFEF6FFFF;\r
313 \r
314   /* Reset HSEBYP bit */\r
315   RCC->CR &= (uint32_t)0xFFFBFFFF;\r
316 \r
317   /* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */\r
318   RCC->CFGR &= (uint32_t)0xFF80FFFF;\r
319 \r
320 #ifndef STM32F10X_CL\r
321   /* Disable all interrupts and clear pending bits  */\r
322   RCC->CIR = 0x009F0000;\r
323 #else\r
324   /* Reset PLL2ON and PLL3ON bits */\r
325   RCC->CR &= (uint32_t)0xEBFFFFFF;\r
326 \r
327   /* Disable all interrupts and clear pending bits  */\r
328   RCC->CIR = 0x00FF0000;\r
329 \r
330   /* Reset CFGR2 register */\r
331   RCC->CFGR2 = 0x00000000;\r
332 #endif /* STM32F10X_CL */\r
333 \r
334   /* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */\r
335   /* Configure the Flash Latency cycles and enable prefetch buffer */\r
336   SetClocks(clockSettingsPtr);\r
337 }\r
338 \r
339 //-------------------------------------------------------------------\r
340 \r
341 void Mcu_Init(const Mcu_ConfigType *configPtr)\r
342 {\r
343   VALIDATE( ( NULL != configPtr ), MCU_INIT_SERVICE_ID, MCU_E_PARAM_CONFIG );\r
344 \r
345 #if !defined(USE_SIMULATOR)\r
346   Mcu_CheckCpu();\r
347 #endif\r
348 \r
349   memset(&Mcu_Global.stats,0,sizeof(Mcu_Global.stats));\r
350 \r
351   Irq_Enable();\r
352 \r
353   Mcu_Global.config = configPtr;\r
354   Mcu_Global.initRun = 1;\r
355 }\r
356 //-------------------------------------------------------------------\r
357 \r
358 void Mcu_DeInit()\r
359 {\r
360   Mcu_Global.initRun = FALSE; // Very simple Deinit. Should we do more?\r
361 }\r
362 \r
363 //-------------------------------------------------------------------\r
364 Std_ReturnType Mcu_InitRamSection(const Mcu_RamSectionType RamSection)\r
365 {\r
366   VALIDATE_W_RV( ( 1 == Mcu_Global.initRun ), MCU_INITRAMSECTION_SERVICE_ID, MCU_E_UNINIT, E_NOT_OK );\r
367   VALIDATE_W_RV( ( RamSection <= Mcu_Global.config->McuRamSectors ), MCU_INITRAMSECTION_SERVICE_ID, MCU_E_PARAM_RAMSECTION, E_NOT_OK );\r
368 \r
369   /* NOT SUPPORTED, reason: no support for external RAM */\r
370 \r
371   return E_OK;\r
372 }\r
373 \r
374 \r
375 \r
376 //-------------------------------------------------------------------\r
377 \r
378 Std_ReturnType Mcu_InitClock(const Mcu_ClockType ClockSetting)\r
379 {\r
380   Mcu_ClockSettingConfigType *clockSettingsPtr;\r
381   VALIDATE_W_RV( ( 1 == Mcu_Global.initRun ), MCU_INITCLOCK_SERVICE_ID, MCU_E_UNINIT, E_NOT_OK );\r
382   VALIDATE_W_RV( ( ClockSetting < Mcu_Global.config->McuClockSettings ), MCU_INITCLOCK_SERVICE_ID, MCU_E_PARAM_CLOCK, E_NOT_OK );\r
383 \r
384   Mcu_Global.clockSetting = ClockSetting;\r
385   clockSettingsPtr = &Mcu_Global.config->McuClockSettingConfig[Mcu_Global.clockSetting];\r
386 \r
387   InitMcuClocks(clockSettingsPtr);\r
388 \r
389   InitPerClocks(clockSettingsPtr);\r
390 \r
391   return E_OK;\r
392 }\r
393 \r
394 //-------------------------------------------------------------------\r
395 \r
396 void Mcu_DistributePllClock(void)\r
397 {\r
398   VALIDATE( ( 1 == Mcu_Global.initRun ), MCU_DISTRIBUTEPLLCLOCK_SERVICE_ID, MCU_E_UNINIT );\r
399 //  VALIDATE( ( FMPLL.SYNSR.B.LOCK == 1 ), MCU_DISTRIBUTEPLLCLOCK_SERVICE_ID, MCU_E_PLL_NOT_LOCKED );\r
400 \r
401   /* NOT IMPLEMENTED due to pointless function on this hardware */\r
402 \r
403 }\r
404 \r
405 //-------------------------------------------------------------------\r
406 \r
407 \r
408 Mcu_PllStatusType Mcu_GetPllStatus(void) {\r
409         VALIDATE_W_RV( ( 1 == Mcu_Global.initRun ), MCU_GETPLLSTATUS_SERVICE_ID, MCU_E_UNINIT, MCU_PLL_STATUS_UNDEFINED );\r
410         Mcu_PllStatusType rv;\r
411 \r
412 #if !defined(USE_SIMULATOR)\r
413         if (RCC->CR & RCC_CR_PLLRDY) {\r
414                 rv = MCU_PLL_LOCKED;\r
415         } else {\r
416                 rv = MCU_PLL_UNLOCKED;\r
417         }\r
418 #else\r
419         /* We are running on instruction set simulator. PLL is then always in sync... */\r
420         rv = MCU_PLL_LOCKED;\r
421 #endif\r
422         return rv;\r
423 }\r
424 \r
425 //-------------------------------------------------------------------\r
426 \r
427 /**\r
428  *\r
429  * @return\r
430  */\r
431 Mcu_ResetType Mcu_GetResetReason(void) {\r
432         Mcu_ResetType rv;\r
433         uint32_t csr;\r
434 \r
435         VALIDATE_W_RV( ( 1 == Mcu_Global.initRun ), MCU_GETRESETREASON_SERVICE_ID, MCU_E_UNINIT, MCU_RESET_UNDEFINED );\r
436 \r
437         csr = RCC->CSR;\r
438 \r
439         if (csr & RCC_CSR_SFTRSTF) {\r
440                 rv = MCU_SW_RESET;\r
441         } else if (csr & (RCC_CSR_IWDGRSTF|RCC_CSR_WWDGRSTF) ) {\r
442                 rv = MCU_WATCHDOG_RESET;\r
443         } else if ( csr & RCC_CSR_PORRSTF ) {\r
444                 rv = MCU_POWER_ON_RESET;\r
445         } else {\r
446                 rv = MCU_RESET_UNDEFINED;\r
447         }\r
448 \r
449         return rv;\r
450 }\r
451 \r
452 //-------------------------------------------------------------------\r
453 \r
454 /**\r
455  * Shall read the raw reset value from hardware register if the hardware\r
456  * supports this.\r
457  *\r
458  * @return\r
459  */\r
460 \r
461 Mcu_RawResetType Mcu_GetResetRawValue(void) {\r
462         VALIDATE_W_RV( ( 1 == Mcu_Global.initRun ), MCU_GETRESETREASON_SERVICE_ID, MCU_E_UNINIT, MCU_GETRESETRAWVALUE_UNINIT_RV );\r
463 \r
464         if (!Mcu_Global.initRun) {\r
465                 return MCU_GETRESETRAWVALUE_UNINIT_RV;\r
466         } else {\r
467                 return (RCC->CSR) & (RCC_CSR_RMVF | RCC_CSR_PINRSTF | RCC_CSR_PORRSTF\r
468                                 | RCC_CSR_SFTRSTF | RCC_CSR_IWDGRSTF | RCC_CSR_WWDGRSTF\r
469                                 | RCC_CSR_LPWRRSTF);\r
470         }\r
471         return 0;\r
472 }\r
473 \r
474 //-------------------------------------------------------------------\r
475 \r
476 #if ( MCU_PERFORM_RESET_API == STD_ON )\r
477 /**\r
478  * Shell perform a microcontroller reset by using the hardware feature\r
479  * of the micro controller.\r
480  */\r
481 void Mcu_PerformReset(void)\r
482 {\r
483   VALIDATE( ( 1 == Mcu_Global.initRun ), MCU_PERFORMRESET_SERVICE_ID, MCU_E_UNINIT );\r
484 \r
485   NVIC_SystemReset();\r
486 }\r
487 #endif\r
488 \r
489 //-------------------------------------------------------------------\r
490 \r
491 void Mcu_SetMode(const Mcu_ModeType McuMode)\r
492 {\r
493   VALIDATE( ( 1 == Mcu_Global.initRun ), MCU_SETMODE_SERVICE_ID, MCU_E_UNINIT );\r
494   VALIDATE( (0), MCU_SETMODE_SERVICE_ID, MCU_E_PARAM_MODE );\r
495   //VALIDATE( ( McuMode <= Mcu_Global.config->McuNumberOfMcuModes ), MCU_SETMODE_SERVICE_ID, MCU_E_PARAM_MODE );\r
496   (void) McuMode;\r
497 \r
498   /* NOT SUPPORTED */\r
499 }\r
500 \r
501 //-------------------------------------------------------------------\r
502 \r
503 /**\r
504  * Get the system clock in Hz. It calculates the clock from the\r
505  * different register settings in HW.\r
506  */\r
507 uint32_t McuE_GetSystemClock(void)\r
508 {\r
509   uint32_t f_sys;\r
510 \r
511   uint32  extal = Mcu_Global.config->McuClockSettingConfig[Mcu_Global.clockSetting].McuClockReferencePointFrequency;\r
512   uint32 pll1 = Mcu_Global.config->McuClockSettingConfig[Mcu_Global.clockSetting].Pll1;\r
513 \r
514 #ifdef STM32F10X_CL\r
515   uint32 pll2 = Mcu_Global.config->McuClockSettingConfig[Mcu_Global.clockSetting].Pll2;\r
516   /* PLL2 configuration: PLL2CLK = (HSE / 5) * PLL2 */\r
517   /* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 */\r
518   /* PLL configuration: PLLCLK = PREDIV1 * PLL1 */\r
519   f_sys = (extal / 5 * pll2) / 5 * pll1;\r
520 #else\r
521   /* PLL configuration: PLLCLK = HSE * PLL1 */\r
522   f_sys = extal * pll1;\r
523 #endif\r
524 \r
525   return f_sys;\r
526 }\r
527 \r
528 imask_t McuE_EnterCriticalSection()\r
529 {\r
530         uint32_t val;\r
531         Irq_Save(val);\r
532         return val;\r
533 }\r
534 \r
535 void McuE_ExitCriticalSection(uint32_t old_state)\r
536 {\r
537         Irq_Restore(old_state);\r
538 }\r
539 \r
540 /**\r
541  * Get the peripheral clock in Hz for a specific device\r
542  */\r
543 uint32_t McuE_GetPeripheralClock(McuE_PeriperalClock_t type)\r
544 {\r
545         uint32_t res = 0;\r
546 \r
547         switch(type)\r
548         {\r
549         case PERIPHERAL_CLOCK_AHB:\r
550                 res = McuE_GetSystemClock();\r
551                 break;\r
552         case PERIPHERAL_CLOCK_APB1:\r
553                 res = McuE_GetSystemClock() / 2;\r
554                 break;\r
555         case PERIPHERAL_CLOCK_APB2:\r
556                 res = McuE_GetSystemClock();\r
557                 break;\r
558         default:\r
559                 break;\r
560         }\r
561 \r
562         return res;\r
563 }\r
564 \r
565 \r
566 /**\r
567  * Function to setup the internal flash for optimal performance\r
568  */\r
569 \r
570 void Mcu_ConfigureFlash(void)\r
571 {\r
572 \r
573 }\r
574 \r
575 void McuE_EnableInterrupts(void)\r
576 {\r
577   Irq_Enable();\r
578 }\r
579 \r
580 void McuE_DisableInterrupts(void)\r
581 {\r
582   Irq_Disable();\r
583 }\r