]> git.sur5r.net Git - freertos/blob - FreeRTOS/Source/portable/GCC/H8S2329/port.c
Convert some ports to use xTaskIncrementTick() in place of vTaskIncrementTick().
[freertos] / FreeRTOS / Source / portable / GCC / H8S2329 / port.c
1 /*\r
2     FreeRTOS V7.4.2 - Copyright (C) 2013 Real Time Engineers Ltd.\r
3 \r
4     FEATURES AND PORTS ARE ADDED TO FREERTOS ALL THE TIME.  PLEASE VISIT\r
5     http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.\r
6 \r
7     ***************************************************************************\r
8      *                                                                       *\r
9      *    FreeRTOS tutorial books are available in pdf and paperback.        *\r
10      *    Complete, revised, and edited pdf reference manuals are also       *\r
11      *    available.                                                         *\r
12      *                                                                       *\r
13      *    Purchasing FreeRTOS documentation will not only help you, by       *\r
14      *    ensuring you get running as quickly as possible and with an        *\r
15      *    in-depth knowledge of how to use FreeRTOS, it will also help       *\r
16      *    the FreeRTOS project to continue with its mission of providing     *\r
17      *    professional grade, cross platform, de facto standard solutions    *\r
18      *    for microcontrollers - completely free of charge!                  *\r
19      *                                                                       *\r
20      *    >>> See http://www.FreeRTOS.org/Documentation for details. <<<     *\r
21      *                                                                       *\r
22      *    Thank you for using FreeRTOS, and thank you for your support!      *\r
23      *                                                                       *\r
24     ***************************************************************************\r
25 \r
26 \r
27     This file is part of the FreeRTOS distribution.\r
28 \r
29     FreeRTOS is free software; you can redistribute it and/or modify it under\r
30     the terms of the GNU General Public License (version 2) as published by the\r
31     Free Software Foundation AND MODIFIED BY the FreeRTOS exception.\r
32 \r
33     >>>>>>NOTE<<<<<< The modification to the GPL is included to allow you to\r
34     distribute a combined work that includes FreeRTOS without being obliged to\r
35     provide the source code for proprietary components outside of the FreeRTOS\r
36     kernel.\r
37 \r
38     FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
39     WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
40     FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more\r
41     details. You should have received a copy of the GNU General Public License\r
42     and the FreeRTOS license exception along with FreeRTOS; if not it can be\r
43     viewed here: http://www.freertos.org/a00114.html and also obtained by\r
44     writing to Real Time Engineers Ltd., contact details for whom are available\r
45     on the FreeRTOS WEB site.\r
46 \r
47     1 tab == 4 spaces!\r
48 \r
49     ***************************************************************************\r
50      *                                                                       *\r
51      *    Having a problem?  Start by reading the FAQ "My application does   *\r
52      *    not run, what could be wrong?"                                     *\r
53      *                                                                       *\r
54      *    http://www.FreeRTOS.org/FAQHelp.html                               *\r
55      *                                                                       *\r
56     ***************************************************************************\r
57 \r
58 \r
59     http://www.FreeRTOS.org - Documentation, books, training, latest versions, \r
60     license and Real Time Engineers Ltd. contact details.\r
61 \r
62     http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
63     including FreeRTOS+Trace - an indispensable productivity tool, and our new\r
64     fully thread aware and reentrant UDP/IP stack.\r
65 \r
66     http://www.OpenRTOS.com - Real Time Engineers ltd license FreeRTOS to High \r
67     Integrity Systems, who sell the code with commercial support, \r
68     indemnification and middleware, under the OpenRTOS brand.\r
69     \r
70     http://www.SafeRTOS.com - High Integrity Systems also provide a safety \r
71     engineered and independently SIL3 certified version for use in safety and \r
72     mission critical applications that require provable dependability.\r
73 */\r
74 \r
75 /* Scheduler includes. */\r
76 #include "FreeRTOS.h"\r
77 #include "task.h"\r
78 \r
79 \r
80 /*-----------------------------------------------------------\r
81  * Implementation of functions defined in portable.h for the H8S port.\r
82  *----------------------------------------------------------*/\r
83 \r
84 \r
85 /*-----------------------------------------------------------*/\r
86 \r
87 /* When the task starts interrupts should be enabled. */\r
88 #define portINITIAL_CCR                 ( ( portSTACK_TYPE ) 0x00 )\r
89 \r
90 /* Hardware specific constants used to generate the RTOS tick from the TPU. */\r
91 #define portCLEAR_ON_TGRA_COMPARE_MATCH ( ( unsigned char ) 0x20 )\r
92 #define portCLOCK_DIV_64                                ( ( unsigned char ) 0x03 )\r
93 #define portCLOCK_DIV                                   ( ( unsigned long ) 64 )\r
94 #define portTGRA_INTERRUPT_ENABLE               ( ( unsigned char ) 0x01 )\r
95 #define portTIMER_CHANNEL                               ( ( unsigned char ) 0x02 )\r
96 #define portMSTP13                                              ( ( unsigned short ) 0x2000 )\r
97 \r
98 /*\r
99  * Setup TPU channel one for the RTOS tick at the requested frequency.\r
100  */\r
101 static void prvSetupTimerInterrupt( void );\r
102 \r
103 /*\r
104  * The ISR used by portYIELD(). This is installed as a trap handler.\r
105  */\r
106 void vPortYield( void ) __attribute__ ( ( saveall, interrupt_handler ) );\r
107 \r
108 /*-----------------------------------------------------------*/\r
109 \r
110 /* \r
111  * See header file for description. \r
112  */\r
113 portSTACK_TYPE *pxPortInitialiseStack( portSTACK_TYPE *pxTopOfStack, pdTASK_CODE pxCode, void *pvParameters )\r
114 {\r
115 unsigned long ulValue;\r
116 \r
117         /* This requires an even address. */\r
118         ulValue = ( unsigned long ) pxTopOfStack;\r
119         if( ulValue & 1UL )\r
120         {\r
121                 pxTopOfStack = pxTopOfStack - 1;\r
122         }\r
123 \r
124         /* Place a few bytes of known values on the bottom of the stack. \r
125         This is just useful for debugging. */\r
126         pxTopOfStack--;\r
127         *pxTopOfStack = 0xaa;\r
128         pxTopOfStack--;\r
129         *pxTopOfStack = 0xbb;\r
130         pxTopOfStack--;\r
131         *pxTopOfStack = 0xcc;\r
132         pxTopOfStack--;\r
133         *pxTopOfStack = 0xdd;\r
134 \r
135         /* The initial stack mimics an interrupt stack.  First there is the program\r
136         counter (24 bits). */\r
137         ulValue = ( unsigned long ) pxCode;\r
138 \r
139         pxTopOfStack--;\r
140         *pxTopOfStack = ( portSTACK_TYPE ) ( ulValue & 0xff );\r
141         pxTopOfStack--;\r
142         ulValue >>= 8UL;\r
143         *pxTopOfStack = ( portSTACK_TYPE ) ( ulValue & 0xff );\r
144         pxTopOfStack--;\r
145         ulValue >>= 8UL;\r
146         *pxTopOfStack = ( portSTACK_TYPE ) ( ulValue & 0xff );\r
147 \r
148         /* Followed by the CCR. */      \r
149         pxTopOfStack--;\r
150         *pxTopOfStack = portINITIAL_CCR;\r
151 \r
152         /* Next all the general purpose registers - with the parameters being passed\r
153         in ER0.  The parameter order must match that used by the compiler when the\r
154         "saveall" function attribute is used. */\r
155 \r
156         /* ER6 */\r
157         pxTopOfStack--;\r
158         *pxTopOfStack = 0x66;\r
159         pxTopOfStack--;\r
160         *pxTopOfStack = 0x66;\r
161         pxTopOfStack--;\r
162         *pxTopOfStack = 0x66;\r
163         pxTopOfStack--;\r
164         *pxTopOfStack = 0x66;\r
165         \r
166         /* ER0 */\r
167         ulValue = ( unsigned long ) pvParameters;\r
168 \r
169         pxTopOfStack--;\r
170         *pxTopOfStack = ( portSTACK_TYPE ) ( ulValue & 0xff );\r
171         pxTopOfStack--;\r
172         ulValue >>= 8UL;\r
173         *pxTopOfStack = ( portSTACK_TYPE ) ( ulValue & 0xff );\r
174         pxTopOfStack--;\r
175         ulValue >>= 8UL;\r
176         *pxTopOfStack = ( portSTACK_TYPE ) ( ulValue & 0xff );\r
177         pxTopOfStack--;\r
178         ulValue >>= 8UL;\r
179         *pxTopOfStack = ( portSTACK_TYPE ) ( ulValue & 0xff );\r
180         \r
181         /* ER1 */\r
182         pxTopOfStack--;\r
183         *pxTopOfStack = 0x11;\r
184         pxTopOfStack--;\r
185         *pxTopOfStack = 0x11;\r
186         pxTopOfStack--;\r
187         *pxTopOfStack = 0x11;\r
188         pxTopOfStack--;\r
189         *pxTopOfStack = 0x11;\r
190 \r
191         /* ER2 */\r
192         pxTopOfStack--;\r
193         *pxTopOfStack = 0x22;\r
194         pxTopOfStack--;\r
195         *pxTopOfStack = 0x22;\r
196         pxTopOfStack--;\r
197         *pxTopOfStack = 0x22;\r
198         pxTopOfStack--;\r
199         *pxTopOfStack = 0x22;\r
200 \r
201         /* ER3 */\r
202         pxTopOfStack--;\r
203         *pxTopOfStack = 0x33;\r
204         pxTopOfStack--;\r
205         *pxTopOfStack = 0x33;\r
206         pxTopOfStack--;\r
207         *pxTopOfStack = 0x33;\r
208         pxTopOfStack--;\r
209         *pxTopOfStack = 0x33;\r
210 \r
211         /* ER4 */\r
212         pxTopOfStack--;\r
213         *pxTopOfStack = 0x44;\r
214         pxTopOfStack--;\r
215         *pxTopOfStack = 0x44;\r
216         pxTopOfStack--;\r
217         *pxTopOfStack = 0x44;\r
218         pxTopOfStack--;\r
219         *pxTopOfStack = 0x44;\r
220 \r
221         /* ER5 */\r
222         pxTopOfStack--;\r
223         *pxTopOfStack = 0x55;\r
224         pxTopOfStack--;\r
225         *pxTopOfStack = 0x55;\r
226         pxTopOfStack--;\r
227         *pxTopOfStack = 0x55;\r
228         pxTopOfStack--;\r
229         *pxTopOfStack = 0x55;\r
230 \r
231         return pxTopOfStack;\r
232 }\r
233 /*-----------------------------------------------------------*/\r
234 \r
235 portBASE_TYPE xPortStartScheduler( void )\r
236 {\r
237 extern void * pxCurrentTCB;\r
238 \r
239         /* Setup the hardware to generate the tick. */\r
240         prvSetupTimerInterrupt();\r
241 \r
242         /* Restore the context of the first task that is going to run.  This\r
243         mirrors the function epilogue code generated by the compiler when the\r
244         "saveall" function attribute is used. */\r
245         asm volatile ( \r
246                                         "MOV.L          @_pxCurrentTCB, ER6                     \n\t"\r
247                                         "MOV.L          @ER6, ER7                                       \n\t"\r
248                                         "LDM.L          @SP+, (ER4-ER5)                         \n\t"\r
249                                         "LDM.L          @SP+, (ER0-ER3)                         \n\t"\r
250                                         "MOV.L          @ER7+, ER6                                      \n\t"\r
251                                         "RTE                                                                    \n\t"\r
252                                 );\r
253 \r
254         ( void ) pxCurrentTCB;\r
255 \r
256         /* Should not get here. */\r
257         return pdTRUE;\r
258 }\r
259 /*-----------------------------------------------------------*/\r
260 \r
261 void vPortEndScheduler( void )\r
262 {\r
263         /* It is unlikely that the h8 port will get stopped. */\r
264 }\r
265 /*-----------------------------------------------------------*/\r
266 \r
267 /*\r
268  * Manual context switch.  This is a trap handler.  The "saveall" function\r
269  * attribute is used so the context is saved by the compiler prologue.  All\r
270  * we have to do is save the stack pointer.\r
271  */\r
272 void vPortYield( void )\r
273 {\r
274         portSAVE_STACK_POINTER();\r
275                 vTaskSwitchContext();\r
276         portRESTORE_STACK_POINTER();\r
277 }\r
278 /*-----------------------------------------------------------*/\r
279 \r
280 /* \r
281  * The interrupt handler installed for the RTOS tick depends on whether the \r
282  * preemptive or cooperative scheduler is being used. \r
283  */\r
284 #if( configUSE_PREEMPTION == 1 )\r
285 \r
286         /* \r
287          * The preemptive scheduler is used so the ISR calls vTaskSwitchContext().\r
288          * The function prologue saves the context so all we have to do is save\r
289          * the stack pointer.\r
290          */\r
291         void vTickISR( void ) __attribute__ ( ( saveall, interrupt_handler ) );\r
292         void vTickISR( void )\r
293         {\r
294                 portSAVE_STACK_POINTER();\r
295                 \r
296                 if( xTaskIncrementTick() != pdFALSE )\r
297                 {\r
298                         vTaskSwitchContext();\r
299                 }\r
300 \r
301                 /* Clear the interrupt. */\r
302                 TSR1 &= ~0x01;\r
303 \r
304                 portRESTORE_STACK_POINTER();\r
305         }\r
306 \r
307 #else\r
308 \r
309         /*\r
310          * The cooperative scheduler is being used so all we have to do is \r
311          * periodically increment the tick.  This can just be a normal ISR and\r
312          * the "saveall" attribute is not required.\r
313          */\r
314         void vTickISR( void ) __attribute__ ( ( interrupt_handler ) );\r
315         void vTickISR( void )\r
316         {\r
317                 xTaskIncrementTick();\r
318 \r
319                 /* Clear the interrupt. */\r
320                 TSR1 &= ~0x01;\r
321         }\r
322 \r
323 #endif\r
324 /*-----------------------------------------------------------*/\r
325 \r
326 /*\r
327  * Setup timer 1 compare match to generate a tick interrupt.\r
328  */\r
329 static void prvSetupTimerInterrupt( void )\r
330 {\r
331 const unsigned long ulCompareMatch = ( configCPU_CLOCK_HZ / configTICK_RATE_HZ ) / portCLOCK_DIV;\r
332 \r
333         /* Turn the module on. */\r
334         MSTPCR &= ~portMSTP13;\r
335 \r
336         /* Configure timer 1. */\r
337         TCR1 = portCLEAR_ON_TGRA_COMPARE_MATCH | portCLOCK_DIV_64;\r
338 \r
339         /* Configure the compare match value for a tick of configTICK_RATE_HZ. */\r
340         TGR1A = ulCompareMatch;\r
341 \r
342         /* Start the timer and enable the interrupt - we can do this here as \r
343         interrupts are globally disabled when this function is called. */\r
344         TIER1 |= portTGRA_INTERRUPT_ENABLE;\r
345         TSTR |= portTIMER_CHANNEL;\r
346 }\r
347 /*-----------------------------------------------------------*/\r
348 \r
349 \r
350 \r