]> rtime.felk.cvut.cz Git - arc.git/blob - arch/hc1x/hcs12d/drivers/Gpt.c
#ifdef:ed all Det includes
[arc.git] / arch / hc1x / hcs12d / drivers / Gpt.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 \r
18 #include "Std_Types.h"\r
19 #include "Gpt.h"\r
20 #include "Cpu.h"\r
21 #include <assert.h>\r
22 #include <string.h>\r
23 #include "regs.h"\r
24 #include "Mcu.h"\r
25 #include "debug.h"\r
26 #if defined(USE_DET)\r
27 #include "Det.h"\r
28 #endif\r
29 #include "Os.h"\r
30 #include "arc.h"\r
31 #include "isr.h"\r
32 \r
33 #define FIRST_OC_REG 0x50\r
34 \r
35 // Implementation specific\r
36 \r
37 #if ( GPT_DEV_ERROR_DETECT == STD_ON )\r
38 #define VALIDATE(_exp,_api,_err ) \\r
39         if( !(_exp) ) { \\r
40           Det_ReportError(MODULE_ID_GPT,0,_api,_err); \\r
41           return; \\r
42         }\r
43 \r
44 #define VALIDATE_W_RV(_exp,_api,_err,_rv ) \\r
45         if( !(_exp) ) { \\r
46           Det_ReportError(MODULE_ID_GPT,0,_api,_err); \\r
47           return (_rv); \\r
48         }\r
49 \r
50 #define VALID_CHANNEL(_ch)              ( Gpt_Global.configured & (1<<(_ch)) )\r
51 \r
52 #else\r
53 #define VALIDATE(_exp,_api,_err )\r
54 #define VALIDATE_W_RV(_exp,_api,_err,_rv )\r
55 #endif\r
56 \r
57 typedef enum\r
58 {\r
59   GPT_STATE_STOPPED = 0,\r
60   GPT_STATE_STARTED,\r
61 } Gpt_StateType;\r
62 \r
63 /**\r
64  * Type that holds all global data for Gpt\r
65  */\r
66 typedef struct\r
67 {\r
68   // Set if Gpt_Init() have been called\r
69   uint8 initRun;\r
70 \r
71   // Our config\r
72   const Gpt_ConfigType *config;\r
73 \r
74   uint8 wakeupEnabled;\r
75 \r
76   // One bit for each channel that is configured.\r
77   // Used to determine if validity of a channel\r
78   // 1 - configured\r
79   // 0 - NOT configured\r
80   uint32 configured;\r
81 \r
82   // Maps the a channel id to a configured channel id\r
83   uint8 channelMap[GPT_CHANNEL_CNT];\r
84 \r
85 } Gpt_GlobalType;\r
86 \r
87 /**\r
88  * Type that holds data that are specific for a channel\r
89  */\r
90 typedef struct\r
91 {\r
92   Gpt_StateType state;\r
93 } Gpt_UnitType;\r
94 \r
95 \r
96 // Holds the enable/disable status of notifications.\r
97 uint8 GptNotificationStatuses[8] = {\r
98         STD_ON,\r
99         STD_ON,\r
100         STD_ON,\r
101         STD_ON,\r
102         STD_ON,\r
103         STD_ON,\r
104         STD_ON,\r
105         STD_ON\r
106 };\r
107 \r
108 uint16 GptPeriods[GPT_CHANNEL_CNT];\r
109 \r
110 #if (GPT_TIME_ELAPSED_API == STD_ON)\r
111 uint16 GptPrevOc[GPT_CHANNEL_CNT];\r
112 #endif\r
113 \r
114 \r
115 Gpt_UnitType Gpt_Unit[GPT_CHANNEL_CNT];\r
116 \r
117 // Global config\r
118 Gpt_GlobalType Gpt_Global;\r
119 \r
120 //-------------------------------------------------------------------\r
121 \r
122 \r
123 /**\r
124  * ISR helper-function that handles the HW channels( 0 to 8 )\r
125  *\r
126  * @param channel - Channel that the raised the interrupt\r
127  */\r
128 static void Gpt_IsrCh(Gpt_ChannelType channel)\r
129 {\r
130   const Gpt_ConfigType *config;\r
131   int confCh;\r
132 \r
133   confCh = Gpt_Global.channelMap[channel];\r
134   assert(confCh != GPT_CHANNEL_ILL);\r
135 \r
136   config = &Gpt_Global.config[confCh];\r
137 \r
138   if (GptNotificationStatuses[channel] == STD_ON) {\r
139          config->GptNotification();\r
140   }\r
141 \r
142   if (config->GptChannelMode == GPT_MODE_ONESHOT)\r
143   {\r
144     // Disable the channel\r
145         Gpt_StopTimer(channel);\r
146     Gpt_Unit[channel].state = GPT_STATE_STOPPED;\r
147 \r
148   } else {\r
149           // Start the next period.\r
150           uint16 curr_oc = PORTIO_16((FIRST_OC_REG + (2 * channel)));\r
151           PORTIO_16((FIRST_OC_REG + (2*channel))) = curr_oc + GptPeriods[channel];\r
152 \r
153           #if (GPT_TIME_ELAPSED_API == STD_ON)\r
154           GptPrevOc[channel] = curr_oc;\r
155           #endif\r
156   }\r
157 \r
158 }\r
159 \r
160 //-------------------------------------------------------------------\r
161 // Macro that counts leading zeroes.\r
162 #define CNTLZW_INV(x) (31-cntlzw(x))\r
163 \r
164 \r
165 /**\r
166  * ISR that handles all interrupts to the PIT channels\r
167  * ( NOT the decrementer )\r
168  */\r
169 #define DECLARE_GPT_ISR_PROTOTYPE(x)                    \\r
170 void Gpt_Isr_##x (void) {                                       \\r
171         Gpt_IsrCh(x);                                                           \\r
172 }\r
173 \r
174 #define GPT_IRQ_TYPE(x) IRQ_TYPE_TC(x)\r
175 \r
176 DECLARE_GPT_ISR_PROTOTYPE(0)\r
177 DECLARE_GPT_ISR_PROTOTYPE(1)\r
178 DECLARE_GPT_ISR_PROTOTYPE(2)\r
179 DECLARE_GPT_ISR_PROTOTYPE(3)\r
180 DECLARE_GPT_ISR_PROTOTYPE(4)\r
181 DECLARE_GPT_ISR_PROTOTYPE(5)\r
182 DECLARE_GPT_ISR_PROTOTYPE(6)\r
183 DECLARE_GPT_ISR_PROTOTYPE(7)\r
184 \r
185 \r
186 //-------------------------------------------------------------------\r
187 \r
188 void Gpt_Init(const Gpt_ConfigType *config)\r
189 {\r
190   uint32_t i=0;\r
191   const Gpt_ConfigType *cfg;\r
192   VALIDATE( (Gpt_Global.initRun == STD_OFF), GPT_INIT_SERVICE_ID, GPT_E_ALREADY_INITIALIZED );\r
193   VALIDATE( (config != NULL ), GPT_INIT_SERVICE_ID, GPT_E_PARAM_CONFIG );\r
194 \r
195   Gpt_ChannelType ch;\r
196 \r
197   for (i=0; i<GPT_CHANNEL_CNT; i++)\r
198   {\r
199     Gpt_Global.channelMap[i] = GPT_CHANNEL_ILL;\r
200   }\r
201 \r
202   i = 0;\r
203   cfg = config;\r
204   while (cfg->GptChannelId != GPT_CHANNEL_ILL)\r
205   {\r
206     ch = cfg->GptChannelId;\r
207 \r
208     // Assign the configuration channel used later..\r
209     Gpt_Global.channelMap[cfg->GptChannelId] = i;\r
210     Gpt_Global.configured |= (1<<ch);\r
211 \r
212     if (ch <= GPT_CHANNEL_7)\r
213     {\r
214       if (cfg->GptNotification != NULL)\r
215       {\r
216         switch (ch) {\r
217         case 0:\r
218                 ISR_INSTALL_ISR2("Gpt_Isr_0",Gpt_Isr_0,IRQ_NR_TC0,1,0);\r
219                 break;\r
220         case 1:\r
221                 ISR_INSTALL_ISR2("Gpt_Isr_1",Gpt_Isr_1,IRQ_NR_TC1,1,0);\r
222             break;\r
223         case 2:\r
224                 ISR_INSTALL_ISR2("Gpt_Isr_2",Gpt_Isr_2,IRQ_NR_TC2,1,0);\r
225                         break;\r
226         case 3:\r
227                 ISR_INSTALL_ISR2("Gpt_Isr_3",Gpt_Isr_3,IRQ_NR_TC3,1,0);\r
228                         break;\r
229         case 4:\r
230                 ISR_INSTALL_ISR2("Gpt_Isr_4",Gpt_Isr_4,IRQ_NR_TC4,1,0);\r
231                         break;\r
232         case 5:\r
233                 ISR_INSTALL_ISR2("Gpt_Isr_5",Gpt_Isr_5,IRQ_NR_TC5,1,0);\r
234                         break;\r
235         case 6:\r
236                 ISR_INSTALL_ISR2("Gpt_Isr_6",Gpt_Isr_6,IRQ_NR_TC6,1,0);\r
237                 break;\r
238         case 7:\r
239                 ISR_INSTALL_ISR2("Gpt_Isr_7",Gpt_Isr_7,IRQ_NR_TC7,1,0);\r
240             break;\r
241         }\r
242       }\r
243     }\r
244 \r
245     cfg++;\r
246     i++;\r
247   }\r
248 \r
249   Gpt_Global.config = config;\r
250 \r
251   Gpt_Global.initRun = STD_ON;\r
252 \r
253   TSCR1 |= TEN; // Turn timer on.\r
254 }\r
255 \r
256 //-------------------------------------------------------------------\r
257 \r
258 #if GPT_DEINIT_API == STD_ON\r
259 void Gpt_DeInit(void)\r
260 {\r
261   Gpt_ChannelType channel;\r
262   VALIDATE( (Gpt_Global.initRun == STD_ON), GPT_DEINIT_SERVICE_ID, GPT_E_UNINIT );\r
263   for (channel=0; channel<GPT_CHANNEL_CNT; channel++) // Validate that all channels have been stopped\r
264   {\r
265     VALIDATE( (Gpt_Unit[channel].state == GPT_STATE_STOPPED), GPT_DEINIT_SERVICE_ID, GPT_E_BUSY );\r
266     Gpt_StopTimer(channel); // Should this be done here?\r
267   }\r
268   Gpt_Global.initRun = STD_OFF;\r
269   Gpt_Global.configured = 0;\r
270   TSCR1 &= ~TEN; // Turn timer off.\r
271   //_config.config = NULL;\r
272 }\r
273 #endif\r
274 \r
275 //-------------------------------------------------------------------\r
276 // period is in "ticks" !!\r
277 void Gpt_StartTimer(Gpt_ChannelType channel, Gpt_ValueType period_ticks)\r
278 {\r
279   int confCh;\r
280 \r
281   VALIDATE( (Gpt_Global.initRun == STD_ON), GPT_STARTTIMER_SERVICE_ID, GPT_E_UNINIT );\r
282   VALIDATE( VALID_CHANNEL(channel), GPT_STARTTIMER_SERVICE_ID, GPT_E_PARAM_CHANNEL );\r
283   VALIDATE( (Gpt_Unit[channel].state == GPT_STATE_STOPPED), GPT_STARTTIMER_SERVICE_ID, GPT_E_BUSY );\r
284   // GPT_E_PARAM_VALUE, all have 32-bit so no need to check\r
285 \r
286   DEBUG(DEBUG_HIGH, "Gpt_StartTimer ch=%d, period=%d [ticks]\n", channel, period_ticks);\r
287 \r
288   confCh = Gpt_Global.channelMap[channel];\r
289 \r
290   if (channel <= GPT_CHANNEL_7) {\r
291 \r
292 \r
293 \r
294         // Setup channel for output compare (OC).\r
295         TIOS |= (1 << channel);\r
296 \r
297         // Enable interrupt for timer\r
298         TIE |= (1 << channel);\r
299 \r
300         // Set OC value.\r
301         uint16 curr_cnt = TCNT;\r
302         PORTIO_16((FIRST_OC_REG + (2*channel))) = curr_cnt + period_ticks;\r
303 \r
304         #if (GPT_TIME_ELAPSED_API == STD_ON)\r
305         GptPrevOc[channel] = curr_cnt;\r
306         #endif\r
307   }\r
308 \r
309   #if ( GPT_ENABLE_DISABLE_NOTIFICATION_API == STD_ON )\r
310   if( Gpt_Global.config[confCh].GptNotification != NULL )\r
311   {\r
312     // GPT275\r
313     Gpt_EnableNotification(channel);\r
314   }\r
315   #endif\r
316 \r
317   GptPeriods[channel] = period_ticks;\r
318   Gpt_Unit[channel].state = GPT_STATE_STARTED;\r
319 }\r
320 \r
321 void Gpt_StopTimer(Gpt_ChannelType channel)\r
322 {\r
323 \r
324   VALIDATE( (Gpt_Global.initRun == STD_ON), GPT_STOPTIMER_SERVICE_ID, GPT_E_UNINIT );\r
325   VALIDATE( VALID_CHANNEL(channel), GPT_STOPTIMER_SERVICE_ID, GPT_E_PARAM_CHANNEL );\r
326 \r
327   if (channel <= GPT_CHANNEL_7)\r
328   {\r
329          TIE &= ~(1 << channel);\r
330   }\r
331 \r
332 #if ( GPT_ENABLE_DISABLE_NOTIFICATION_API == STD_ON )\r
333   Gpt_DisableNotification(channel);\r
334 #endif\r
335 \r
336   Gpt_Unit[channel].state = GPT_STATE_STOPPED;\r
337 }\r
338 \r
339 \r
340 #if ( GPT_TIME_REMAINING_API == STD_ON )\r
341 Gpt_ValueType Gpt_GetTimeRemaining(Gpt_ChannelType channel)\r
342 {\r
343   VALIDATE_W_RV( (Gpt_Global.initRun == STD_ON), GPT_GETTIMEREMAINING_SERVICE_ID, GPT_E_UNINIT, 0 );\r
344   VALIDATE_W_RV( VALID_CHANNEL(channel),GPT_GETTIMEREMAINING_SERVICE_ID, GPT_E_PARAM_CHANNEL, 0 );\r
345   VALIDATE_W_RV( (Gpt_Unit[channel].state == GPT_STATE_STARTED), GPT_GETTIMEREMAINING_SERVICE_ID, GPT_E_NOT_STARTED, 0 );\r
346   Gpt_ValueType remaining = 0;\r
347 \r
348   if (channel <= GPT_CHANNEL_7)\r
349   {\r
350           uint16 now = TCNT;\r
351           uint16 next = PORTIO_16((FIRST_OC_REG + (2*channel)));\r
352           if (next > now) {\r
353                   remaining = next - now;\r
354 \r
355           } else {\r
356                   remaining = next + (0xFF - now) ;\r
357           }\r
358   }\r
359 \r
360   return remaining;\r
361 }\r
362 #endif\r
363 \r
364 #if ( GPT_TIME_ELAPSED_API == STD_ON )\r
365 Gpt_ValueType Gpt_GetTimeElapsed(Gpt_ChannelType channel)\r
366 {\r
367   Gpt_ValueType elapsed = 0;\r
368 \r
369   VALIDATE_W_RV( (Gpt_Global.initRun == STD_ON), GPT_GETTIMEELAPSED_SERVICE_ID, GPT_E_UNINIT ,0 );\r
370   VALIDATE_W_RV( VALID_CHANNEL(channel),GPT_GETTIMEELAPSED_SERVICE_ID, GPT_E_PARAM_CHANNEL, 0 );\r
371   VALIDATE_W_RV( (Gpt_Unit[channel].state == GPT_STATE_STARTED),GPT_GETTIMEELAPSED_SERVICE_ID, GPT_E_NOT_STARTED, 0 );\r
372 \r
373   if (channel <= GPT_CHANNEL_7) {\r
374     uint16 now = TCNT;\r
375     if (now > GptPrevOc[channel]) {\r
376         elapsed = now - GptPrevOc[channel];\r
377 \r
378     } else {\r
379         elapsed = (0xFF - GptPrevOc[channel]) + now;\r
380     }\r
381   }\r
382 \r
383   return (elapsed);\r
384 }\r
385 #endif\r
386 \r
387 #if ( GPT_ENABLE_DISABLE_NOTIFICATION_API == STD_ON )\r
388 void Gpt_EnableNotification(Gpt_ChannelType channel)\r
389 {\r
390 \r
391   VALIDATE( (Gpt_Global.initRun == STD_ON), 0x7, GPT_E_UNINIT );\r
392   VALIDATE( VALID_CHANNEL(channel),0x7, GPT_E_PARAM_CHANNEL );\r
393 \r
394   if (channel <= GPT_CHANNEL_7)\r
395   {\r
396           GptNotificationStatuses[channel] = STD_ON;\r
397   }\r
398 }\r
399 \r
400 void Gpt_DisableNotification(Gpt_ChannelType channel)\r
401 {\r
402   VALIDATE( (Gpt_Global.initRun == STD_ON), 0x8, GPT_E_UNINIT );\r
403   VALIDATE( VALID_CHANNEL(channel),0x8, GPT_E_PARAM_CHANNEL );\r
404 \r
405   if (channel <= GPT_CHANNEL_7)\r
406   {\r
407           GptNotificationStatuses[channel] = STD_OFF;\r
408   }\r
409 }\r
410 #endif\r
411 \r
412 #if ( GPT_WAKEUP_FUNCTIONALITY_API == STD_ON )\r
413 \r
414 void Gpt_SetMode(Gpt_ModeType mode)\r
415 {\r
416   int i;\r
417 \r
418   VALIDATE( (Gpt_Global.initRun == STD_ON), GPT_SETMODE_SERVIVCE_ID, GPT_E_UNINIT );\r
419   VALIDATE( ( mode <= GPT_MODE_SLEEP ), GPT_SETMODE_SERVIVCE_ID, GPT_E_PARAM_MODE );\r
420 \r
421   if (mode == GPT_MODE_NORMAL)\r
422   {\r
423 \r
424   }\r
425   else if (mode == GPT_MODE_SLEEP)\r
426   {\r
427 \r
428   }\r
429 }\r
430 \r
431 void Gpt_DisableWakeup(Gpt_ChannelType channel)\r
432 {\r
433   VALIDATE( (Gpt_Global.initRun == STD_ON), GPT_DISABLEWAKEUP_SERVICE_ID, GPT_E_UNINIT );\r
434   VALIDATE( VALID_CHANNEL(channel), GPT_DISABLEWAKEUP_SERVICE_ID, GPT_E_PARAM_CHANNEL );\r
435 \r
436 \r
437 }\r
438 \r
439 void Gpt_EnableWakeup(Gpt_ChannelType channel)\r
440 {\r
441   VALIDATE( (Gpt_Global.initRun == STD_ON), GPT_ENABLEWAKEUP_SERVICE_ID, GPT_E_UNINIT );\r
442   VALIDATE( VALID_CHANNEL(channel),GPT_ENABLEWAKEUP_SERVICE_ID, GPT_E_PARAM_CHANNEL );\r
443 \r
444 }\r
445 \r
446 void Gpt_Cbk_CheckWakeup(EcuM_WakeupSourceType wakeupSource)\r
447 {\r
448 \r
449 }\r
450 \r
451 #endif\r
452 \r