]> git.sur5r.net Git - freertos/blob - FreeRTOS/Source/portable/MPLAB/PIC24_dsPIC/port.c
77ef499095a84cd52d1055f68f5d2af94b2aad37
[freertos] / FreeRTOS / Source / portable / MPLAB / PIC24_dsPIC / port.c
1 /*\r
2     FreeRTOS V8.2.3 - Copyright (C) 2015 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     This file is part of the FreeRTOS distribution.\r
8 \r
9     FreeRTOS is free software; you can redistribute it and/or modify it under\r
10     the terms of the GNU General Public License (version 2) as published by the\r
11     Free Software Foundation >>>> AND MODIFIED BY <<<< the FreeRTOS exception.\r
12 \r
13     ***************************************************************************\r
14     >>!   NOTE: The modification to the GPL is included to allow you to     !<<\r
15     >>!   distribute a combined work that includes FreeRTOS without being   !<<\r
16     >>!   obliged to provide the source code for proprietary components     !<<\r
17     >>!   outside of the FreeRTOS kernel.                                   !<<\r
18     ***************************************************************************\r
19 \r
20     FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY\r
21     WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS\r
22     FOR A PARTICULAR PURPOSE.  Full license text is available on the following\r
23     link: http://www.freertos.org/a00114.html\r
24 \r
25     ***************************************************************************\r
26      *                                                                       *\r
27      *    FreeRTOS provides completely free yet professionally developed,    *\r
28      *    robust, strictly quality controlled, supported, and cross          *\r
29      *    platform software that is more than just the market leader, it     *\r
30      *    is the industry's de facto standard.                               *\r
31      *                                                                       *\r
32      *    Help yourself get started quickly while simultaneously helping     *\r
33      *    to support the FreeRTOS project by purchasing a FreeRTOS           *\r
34      *    tutorial book, reference manual, or both:                          *\r
35      *    http://www.FreeRTOS.org/Documentation                              *\r
36      *                                                                       *\r
37     ***************************************************************************\r
38 \r
39     http://www.FreeRTOS.org/FAQHelp.html - Having a problem?  Start by reading\r
40     the FAQ page "My application does not run, what could be wrong?".  Have you\r
41     defined configASSERT()?\r
42 \r
43     http://www.FreeRTOS.org/support - In return for receiving this top quality\r
44     embedded software for free we request you assist our global community by\r
45     participating in the support forum.\r
46 \r
47     http://www.FreeRTOS.org/training - Investing in training allows your team to\r
48     be as productive as possible as early as possible.  Now you can receive\r
49     FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers\r
50     Ltd, and the world's leading authority on the world's leading RTOS.\r
51 \r
52     http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,\r
53     including FreeRTOS+Trace - an indispensable productivity tool, a DOS\r
54     compatible FAT file system, and our tiny thread aware UDP/IP stack.\r
55 \r
56     http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate.\r
57     Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS.\r
58 \r
59     http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High\r
60     Integrity Systems ltd. to sell under the OpenRTOS brand.  Low cost OpenRTOS\r
61     licenses offer ticketed support, indemnification and commercial middleware.\r
62 \r
63     http://www.SafeRTOS.com - High Integrity Systems also provide a safety\r
64     engineered and independently SIL3 certified version for use in safety and\r
65     mission critical applications that require provable dependability.\r
66 \r
67     1 tab == 4 spaces!\r
68 */\r
69 \r
70 /*\r
71         Changes from V4.2.1\r
72 \r
73         + Introduced the configKERNEL_INTERRUPT_PRIORITY definition.\r
74 */\r
75 \r
76 /*-----------------------------------------------------------\r
77  * Implementation of functions defined in portable.h for the PIC24 port.\r
78  *----------------------------------------------------------*/\r
79 \r
80 /* Scheduler include files. */\r
81 #include "FreeRTOS.h"\r
82 #include "task.h"\r
83 \r
84 /* Hardware specifics. */\r
85 #define portBIT_SET 1\r
86 #define portTIMER_PRESCALE 8\r
87 #define portINITIAL_SR  0\r
88 \r
89 /* Defined for backward compatability with project created prior to\r
90 FreeRTOS.org V4.3.0. */\r
91 #ifndef configKERNEL_INTERRUPT_PRIORITY\r
92         #define configKERNEL_INTERRUPT_PRIORITY 1\r
93 #endif\r
94 \r
95 /* Use _T1Interrupt as the interrupt handler name if the application writer has\r
96 not provided their own. */\r
97 #ifndef configTICK_INTERRUPT_HANDLER\r
98         #define configTICK_INTERRUPT_HANDLER _T1Interrupt\r
99 #endif /* configTICK_INTERRUPT_HANDLER */\r
100 \r
101 /* The program counter is only 23 bits. */\r
102 #define portUNUSED_PR_BITS      0x7f\r
103 \r
104 /* Records the nesting depth of calls to portENTER_CRITICAL(). */\r
105 UBaseType_t uxCriticalNesting = 0xef;\r
106 \r
107 #if configKERNEL_INTERRUPT_PRIORITY != 1\r
108         #error If configKERNEL_INTERRUPT_PRIORITY is not 1 then the #32 in the following macros needs changing to equal the portINTERRUPT_BITS value, which is ( configKERNEL_INTERRUPT_PRIORITY << 5 )\r
109 #endif\r
110 \r
111 #if defined( __PIC24E__ ) || defined ( __PIC24F__ ) || defined( __PIC24FK__ ) || defined( __PIC24H__ )\r
112 \r
113     #ifdef __HAS_EDS__\r
114                 #define portRESTORE_CONTEXT()                                                                                                                                                                           \\r
115                                         asm volatile(   "MOV    _pxCurrentTCB, W0               \n"     /* Restore the stack pointer for the task. */           \\r
116                                                         "MOV    [W0], W15                               \n"                                                                                                                             \\r
117                                                         "POP    W0                                              \n"     /* Restore the critical nesting counter for the task. */        \\r
118                                                         "MOV    W0, _uxCriticalNesting  \n"                                                                                                                             \\r
119                                                         "POP    DSWPAG                                  \n"                                                                                                                             \\r
120                                                         "POP    DSRPAG                                  \n"                                                                                                                             \\r
121                                                         "POP    CORCON                                  \n"                                                                                                                             \\r
122                                                         "POP    TBLPAG                                  \n"                                                                                                                             \\r
123                                                         "POP    RCOUNT                                  \n"     /* Restore the registers from the stack. */                                     \\r
124                                                         "POP    W14                                             \n"                                                                                                                             \\r
125                                                         "POP.D  W12                                             \n"                                                                                                                             \\r
126                                                         "POP.D  W10                                             \n"                                                                                                                             \\r
127                                                         "POP.D  W8                                              \n"                                                                                                                             \\r
128                                                         "POP.D  W6                                              \n"                                                                                                                             \\r
129                                                         "POP.D  W4                                              \n"                                                                                                                             \\r
130                                                         "POP.D  W2                                              \n"                                                                                                                             \\r
131                                                         "POP.D  W0                                              \n"                                                                                                                             \\r
132                                                         "POP    SR                                                " );\r
133         #else /* __HAS_EDS__ */\r
134                 #define portRESTORE_CONTEXT()                                                                                                                                                                           \\r
135                         asm volatile(   "MOV    _pxCurrentTCB, W0               \n"     /* Restore the stack pointer for the task. */                           \\r
136                                                         "MOV    [W0], W15                               \n"                                                                                                                             \\r
137                                                         "POP    W0                                              \n"     /* Restore the critical nesting counter for the task. */        \\r
138                                                         "MOV    W0, _uxCriticalNesting  \n"                                                                                                                             \\r
139                                                         "POP    PSVPAG                                  \n"                                                                                                                             \\r
140                                                         "POP    CORCON                                  \n"                                                                                                                             \\r
141                                                         "POP    TBLPAG                                  \n"                                                                                                                             \\r
142                                                         "POP    RCOUNT                                  \n"     /* Restore the registers from the stack. */                                     \\r
143                                                         "POP    W14                                             \n"                                                                                                                             \\r
144                                                         "POP.D  W12                                             \n"                                                                                                                             \\r
145                                                         "POP.D  W10                                             \n"                                                                                                                             \\r
146                                                         "POP.D  W8                                              \n"                                                                                                                             \\r
147                                                         "POP.D  W6                                              \n"                                                                                                                             \\r
148                                                         "POP.D  W4                                              \n"                                                                                                                             \\r
149                                                         "POP.D  W2                                              \n"                                                                                                                             \\r
150                                                         "POP.D  W0                                              \n"                                                                                                                             \\r
151                                                         "POP    SR                                                " );\r
152                 #endif /* __HAS_EDS__ */\r
153 #endif /* MPLAB_PIC24_PORT */\r
154 \r
155 #if defined( __dsPIC30F__ ) || defined( __dsPIC33F__ )\r
156 \r
157         #define portRESTORE_CONTEXT()                                                                                                                                                                           \\r
158                 asm volatile(   "MOV    _pxCurrentTCB, W0               \n"     /* Restore the stack pointer for the task. */                           \\r
159                                                 "MOV    [W0], W15                               \n"                                                                                                                             \\r
160                                                 "POP    W0                                              \n"     /* Restore the critical nesting counter for the task. */        \\r
161                                                 "MOV    W0, _uxCriticalNesting  \n"                                                                                                                             \\r
162                                                 "POP    PSVPAG                                  \n"                                                                                                                             \\r
163                                                 "POP    CORCON                                  \n"                                                                                                                             \\r
164                                                 "POP    DOENDH                                  \n"                                                                                                                             \\r
165                                                 "POP    DOENDL                                  \n"                                                                                                                             \\r
166                                                 "POP    DOSTARTH                                \n"                                                                                                                             \\r
167                                                 "POP    DOSTARTL                                \n"                                                                                                                             \\r
168                                                 "POP    DCOUNT                                  \n"                                                                                                                             \\r
169                                                 "POP    ACCBU                                   \n"                                                                                                                             \\r
170                                                 "POP    ACCBH                                   \n"                                                                                                                             \\r
171                                                 "POP    ACCBL                                   \n"                                                                                                                             \\r
172                                                 "POP    ACCAU                                   \n"                                                                                                                             \\r
173                                                 "POP    ACCAH                                   \n"                                                                                                                             \\r
174                                                 "POP    ACCAL                                   \n"                                                                                                                             \\r
175                                                 "POP    TBLPAG                                  \n"                                                                                                                             \\r
176                                                 "POP    RCOUNT                                  \n"     /* Restore the registers from the stack. */                                     \\r
177                                                 "POP    W14                                             \n"                                                                                                                             \\r
178                                                 "POP.D  W12                                             \n"                                                                                                                             \\r
179                                                 "POP.D  W10                                             \n"                                                                                                                             \\r
180                                                 "POP.D  W8                                              \n"                                                                                                                             \\r
181                                                 "POP.D  W6                                              \n"                                                                                                                             \\r
182                                                 "POP.D  W4                                              \n"                                                                                                                             \\r
183                                                 "POP.D  W2                                              \n"                                                                                                                             \\r
184                                                 "POP.D  W0                                              \n"                                                                                                                             \\r
185                                                 "POP    SR                                                " );\r
186 \r
187 #endif /* MPLAB_DSPIC_PORT */\r
188 \r
189 #ifndef portRESTORE_CONTEXT\r
190         #error Unrecognised device selected\r
191 \r
192         /* Note:  dsPIC parts with EDS are not supported as there is no easy way to\r
193         recover the hardware stacked copies for DOCOUNT, DOHIGH, DOLOW. */\r
194 #endif\r
195 \r
196 /*\r
197  * Setup the timer used to generate the tick interrupt.\r
198  */\r
199 void vApplicationSetupTickTimerInterrupt( void );\r
200 \r
201 /*\r
202  * See header file for description.\r
203  */\r
204 StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )\r
205 {\r
206 uint16_t usCode;\r
207 UBaseType_t i;\r
208 \r
209 const StackType_t xInitialStack[] =\r
210 {\r
211         0x1111, /* W1 */\r
212         0x2222, /* W2 */\r
213         0x3333, /* W3 */\r
214         0x4444, /* W4 */\r
215         0x5555, /* W5 */\r
216         0x6666, /* W6 */\r
217         0x7777, /* W7 */\r
218         0x8888, /* W8 */\r
219         0x9999, /* W9 */\r
220         0xaaaa, /* W10 */\r
221         0xbbbb, /* W11 */\r
222         0xcccc, /* W12 */\r
223         0xdddd, /* W13 */\r
224         0xeeee, /* W14 */\r
225         0xcdce, /* RCOUNT */\r
226         0xabac, /* TBLPAG */\r
227 \r
228         /* dsPIC specific registers. */\r
229         #ifdef MPLAB_DSPIC_PORT\r
230                 0x0202, /* ACCAL */\r
231                 0x0303, /* ACCAH */\r
232                 0x0404, /* ACCAU */\r
233                 0x0505, /* ACCBL */\r
234                 0x0606, /* ACCBH */\r
235                 0x0707, /* ACCBU */\r
236                 0x0808, /* DCOUNT */\r
237                 0x090a, /* DOSTARTL */\r
238                 0x1010, /* DOSTARTH */\r
239                 0x1110, /* DOENDL */\r
240                 0x1212, /* DOENDH */\r
241         #endif\r
242 };\r
243 \r
244         /* Setup the stack as if a yield had occurred.\r
245 \r
246         Save the low bytes of the program counter. */\r
247         usCode = ( uint16_t ) pxCode;\r
248         *pxTopOfStack = ( StackType_t ) usCode;\r
249         pxTopOfStack++;\r
250 \r
251         /* Save the high byte of the program counter.  This will always be zero\r
252         here as it is passed in a 16bit pointer.  If the address is greater than\r
253         16 bits then the pointer will point to a jump table. */\r
254         *pxTopOfStack = ( StackType_t ) 0;\r
255         pxTopOfStack++;\r
256 \r
257         /* Status register with interrupts enabled. */\r
258         *pxTopOfStack = portINITIAL_SR;\r
259         pxTopOfStack++;\r
260 \r
261         /* Parameters are passed in W0. */\r
262         *pxTopOfStack = ( StackType_t ) pvParameters;\r
263         pxTopOfStack++;\r
264 \r
265         for( i = 0; i < ( sizeof( xInitialStack ) / sizeof( StackType_t ) ); i++ )\r
266         {\r
267                 *pxTopOfStack = xInitialStack[ i ];\r
268                 pxTopOfStack++;\r
269         }\r
270 \r
271         *pxTopOfStack = CORCON;\r
272         pxTopOfStack++;\r
273 \r
274         #if defined(__HAS_EDS__)\r
275                 *pxTopOfStack = DSRPAG;\r
276                 pxTopOfStack++;\r
277                 *pxTopOfStack = DSWPAG;\r
278                 pxTopOfStack++;\r
279         #else /* __HAS_EDS__ */\r
280                 *pxTopOfStack = PSVPAG;\r
281                 pxTopOfStack++;\r
282         #endif /* __HAS_EDS__ */\r
283 \r
284         /* Finally the critical nesting depth. */\r
285         *pxTopOfStack = 0x00;\r
286         pxTopOfStack++;\r
287 \r
288         return pxTopOfStack;\r
289 }\r
290 /*-----------------------------------------------------------*/\r
291 \r
292 BaseType_t xPortStartScheduler( void )\r
293 {\r
294         /* Setup a timer for the tick ISR. */\r
295         vApplicationSetupTickTimerInterrupt();\r
296 \r
297         /* Restore the context of the first task to run. */\r
298         portRESTORE_CONTEXT();\r
299 \r
300         /* Simulate the end of the yield function. */\r
301         asm volatile ( "return" );\r
302 \r
303         /* Should not reach here. */\r
304         return pdTRUE;\r
305 }\r
306 /*-----------------------------------------------------------*/\r
307 \r
308 void vPortEndScheduler( void )\r
309 {\r
310         /* Not implemented in ports where there is nothing to return to.\r
311         Artificially force an assert. */\r
312         configASSERT( uxCriticalNesting == 1000UL );\r
313 }\r
314 /*-----------------------------------------------------------*/\r
315 \r
316 /*\r
317  * Setup a timer for a regular tick.\r
318  */\r
319 __attribute__(( weak )) void vApplicationSetupTickTimerInterrupt( void )\r
320 {\r
321 const uint32_t ulCompareMatch = ( ( configCPU_CLOCK_HZ / portTIMER_PRESCALE ) / configTICK_RATE_HZ ) - 1;\r
322 \r
323         /* Prescale of 8. */\r
324         T1CON = 0;\r
325         TMR1 = 0;\r
326 \r
327         PR1 = ( uint16_t ) ulCompareMatch;\r
328 \r
329         /* Setup timer 1 interrupt priority. */\r
330         IPC0bits.T1IP = configKERNEL_INTERRUPT_PRIORITY;\r
331 \r
332         /* Clear the interrupt as a starting condition. */\r
333         IFS0bits.T1IF = 0;\r
334 \r
335         /* Enable the interrupt. */\r
336         IEC0bits.T1IE = 1;\r
337 \r
338         /* Setup the prescale value. */\r
339         T1CONbits.TCKPS0 = 1;\r
340         T1CONbits.TCKPS1 = 0;\r
341 \r
342         /* Start the timer. */\r
343         T1CONbits.TON = 1;\r
344 }\r
345 /*-----------------------------------------------------------*/\r
346 \r
347 void vPortEnterCritical( void )\r
348 {\r
349         portDISABLE_INTERRUPTS();\r
350         uxCriticalNesting++;\r
351 }\r
352 /*-----------------------------------------------------------*/\r
353 \r
354 void vPortExitCritical( void )\r
355 {\r
356         configASSERT( uxCriticalNesting );\r
357         uxCriticalNesting--;\r
358         if( uxCriticalNesting == 0 )\r
359         {\r
360                 portENABLE_INTERRUPTS();\r
361         }\r
362 }\r
363 /*-----------------------------------------------------------*/\r
364 \r
365 void __attribute__((__interrupt__, auto_psv)) configTICK_INTERRUPT_HANDLER( void )\r
366 {\r
367         /* Clear the timer interrupt. */\r
368         IFS0bits.T1IF = 0;\r
369 \r
370         if( xTaskIncrementTick() != pdFALSE )\r
371         {\r
372                 portYIELD();\r
373         }\r
374 }\r
375 \r