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