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