]> rtime.felk.cvut.cz Git - arc.git/blob - system/EcuM/EcuM_Main.c
Merged in old bugfix
[arc.git] / system / EcuM / EcuM_Main.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 //lint -emacro(904,VALIDATE,VALIDATE_RV,VALIDATE_NO_RV) //904 PC-Lint exception to MISRA 14.7 (validate macros).\r
17 \r
18 #include "EcuM.h"\r
19 #include "EcuM_Cbk.h"\r
20 #include "EcuM_Internals.h"\r
21 #if defined(USE_DEM)\r
22 #include "Dem.h"\r
23 #endif\r
24 #if defined(USE_NVM)\r
25 #include "Nvm.h"\r
26 #endif\r
27 \r
28 static uint32 internal_data_run_state_timeout = 0;\r
29 #if defined(USE_NVM)\r
30 static uint32 internal_data_go_off_one_state_timeout = 0;\r
31 static NvM_RequestResultType writeAllResult;\r
32 #endif\r
33 \r
34 \r
35 void EcuM_enter_run_mode(void){\r
36         internal_data.current_state = ECUM_STATE_APP_RUN;\r
37         EcuM_OnEnterRUN(); /** @req EcuM2308 */\r
38         //TODO: Call ComM_EcuM_RunModeIndication(NetworkHandleType Channel) for all channels that have requested run.\r
39         internal_data_run_state_timeout = internal_data.config->EcuMRunMinimumDuration / ECUM_MAIN_FUNCTION_PERIOD; /** @req EcuM2310 */\r
40 }\r
41 \r
42 \r
43 //--------- Local functions ------------------------------------------------------------------------------------------------\r
44 \r
45 static inline void enter_go_sleep_mode(void){\r
46         internal_data.current_state = ECUM_STATE_GO_SLEEP;\r
47         EcuM_OnGoSleep();\r
48 }\r
49 \r
50 static inline void enter_go_off_one_mode(void){\r
51         internal_data.current_state = ECUM_STATE_GO_OFF_ONE;\r
52         EcuM_OnGoOffOne();\r
53 \r
54 #if defined(USE_COMM)\r
55         ComM_DeInit();\r
56 #endif\r
57 \r
58 #if defined(USE_NVM)\r
59 \r
60         // Start NvM_WriteAll and timeout timer\r
61         NvM_WriteAll();\r
62 \r
63         internal_data_go_off_one_state_timeout = internal_data.config->EcuMNvramWriteAllTimeout / ECUM_MAIN_FUNCTION_PERIOD;\r
64 #endif\r
65 }\r
66 \r
67 \r
68 static inline boolean hasRunRequests(void){\r
69         uint32 result = internal_data.run_requests;\r
70 \r
71 #if defined(USE_COMM)\r
72         result |= internal_data.run_comm_requests;\r
73 #endif\r
74 \r
75         return (result != 0);\r
76 }\r
77 \r
78 static inline boolean hasPostRunRequests(void){\r
79         return (internal_data.postrun_requests != 0);\r
80 }\r
81 \r
82 \r
83 \r
84 static inline void in_state_appRun(void){\r
85         if (internal_data_run_state_timeout){\r
86                 internal_data_run_state_timeout--;\r
87         }\r
88 \r
89         if ((!hasRunRequests()) && (internal_data_run_state_timeout == 0)){\r
90                 EcuM_OnExitRun();       /** @req EcuM2865 */\r
91                 internal_data.current_state = ECUM_STATE_APP_POST_RUN;/** @req EcuM2865 */\r
92         }\r
93 }\r
94 \r
95 \r
96 static inline void in_state_appPostRun(void){\r
97         if (hasRunRequests()){\r
98                 internal_data.current_state = ECUM_STATE_APP_RUN;/** @req EcuM2866 */ /** @req EcuM2308 */\r
99                 EcuM_OnEnterRUN(); /** @req EcuM2308 */\r
100                 //TODO: Call ComM_EcuM_RunModeIndication(NetworkHandleType Channel) for all channels that have requested run.\r
101                 internal_data_run_state_timeout = internal_data.config->EcuMRunMinimumDuration / ECUM_MAIN_FUNCTION_PERIOD; /** @req EcuM2310 */\r
102 \r
103         } else if (!hasPostRunRequests()){\r
104                 EcuM_OnExitPostRun(); /** @req EcuM2761 */\r
105                 internal_data.current_state = ECUM_STATE_PREP_SHUTDOWN;/** @req EcuM2761 */\r
106 \r
107                 EcuM_OnPrepShutdown();\r
108         } else {\r
109                 // TODO: Do something?\r
110         }\r
111 }\r
112 \r
113 static inline void in_state_prepShutdown(void){\r
114 #if defined(USE_DEM)\r
115         // DEM shutdown\r
116         Dem_Shutdown();\r
117 #endif\r
118 \r
119         // Switch shutdown mode\r
120         switch(internal_data.shutdown_target){\r
121                 //If in state Off or Reset go into Go_Off_One:\r
122                 case ECUM_STATE_OFF:\r
123                 case ECUM_STATE_RESET:\r
124                         enter_go_off_one_mode();\r
125                         break;\r
126                 case ECUM_STATE_SLEEP:\r
127                         enter_go_sleep_mode();\r
128                         break;\r
129                 default:\r
130                         //TODO: Report error.\r
131                         break;\r
132         }\r
133 }\r
134 \r
135 static inline void in_state_goOffOne(void){\r
136 #if defined(USE_NVM)\r
137                 if (internal_data_go_off_one_state_timeout){\r
138                         internal_data_go_off_one_state_timeout--;\r
139                 }\r
140                 // Wait for the NVM job (NvmWriteAll) to terminate\r
141                 NvM_GetErrorStatus(0, &writeAllResult);\r
142                 if ((writeAllResult != NVM_REQ_PENDING) || (internal_data_go_off_one_state_timeout == 0)){\r
143                         ShutdownOS(E_OK);\r
144                 }\r
145 #else\r
146                 ShutdownOS(E_OK);\r
147 #endif\r
148 }\r
149 \r
150 \r
151 //----- MAIN -----------------------------------------------------------------------------------------------------------------\r
152 void EcuM_MainFunction(void){\r
153         VALIDATE_NO_RV(internal_data.initiated, ECUM_MAINFUNCTION_ID, ECUM_E_NOT_INITIATED);\r
154 \r
155         switch(internal_data.current_state){\r
156 \r
157                 case ECUM_STATE_APP_RUN:\r
158                         in_state_appRun();\r
159                         break;\r
160                 case ECUM_STATE_APP_POST_RUN:\r
161                         in_state_appPostRun();\r
162                         break;\r
163                 case ECUM_STATE_PREP_SHUTDOWN:\r
164                         in_state_prepShutdown();\r
165                         break;\r
166                 case ECUM_STATE_GO_OFF_ONE:\r
167                         in_state_goOffOne();\r
168                         break;\r
169                 case ECUM_STATE_GO_SLEEP:\r
170                         // TODO: Fill out\r
171                         break;\r
172                 default:\r
173                         //TODO: Report error.\r
174                         break;\r
175         }\r
176 }\r