]> git.sur5r.net Git - freertos/blob - FreeRTOS/Source/portable/MPLAB/PIC24_dsPIC/port.c
Update to MIT licensed FreeRTOS V10.0.0 - see https://www.freertos.org/History.txt
[freertos] / FreeRTOS / Source / portable / MPLAB / PIC24_dsPIC / port.c
1 /*\r
2  * FreeRTOS Kernel V10.0.0\r
3  * Copyright (C) 2017 Amazon.com, Inc. or its affiliates.  All Rights Reserved.\r
4  *\r
5  * Permission is hereby granted, free of charge, to any person obtaining a copy of\r
6  * this software and associated documentation files (the "Software"), to deal in\r
7  * the Software without restriction, including without limitation the rights to\r
8  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\r
9  * the Software, and to permit persons to whom the Software is furnished to do so,\r
10  * subject to the following conditions:\r
11  *\r
12  * The above copyright notice and this permission notice shall be included in all\r
13  * copies or substantial portions of the Software. If you wish to use our Amazon\r
14  * FreeRTOS name, please do so in a fair use way that does not cause confusion.\r
15  *\r
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\r
18  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\r
19  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
20  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
22  *\r
23  * http://www.FreeRTOS.org\r
24  * http://aws.amazon.com/freertos\r
25  *\r
26  * 1 tab == 4 spaces!\r
27  */\r
28 \r
29 /*\r
30         Changes from V4.2.1\r
31 \r
32         + Introduced the configKERNEL_INTERRUPT_PRIORITY definition.\r
33 */\r
34 \r
35 /*-----------------------------------------------------------\r
36  * Implementation of functions defined in portable.h for the PIC24 port.\r
37  *----------------------------------------------------------*/\r
38 \r
39 /* Scheduler include files. */\r
40 #include "FreeRTOS.h"\r
41 #include "task.h"\r
42 \r
43 /* Hardware specifics. */\r
44 #define portBIT_SET 1\r
45 #define portTIMER_PRESCALE 8\r
46 #define portINITIAL_SR  0\r
47 \r
48 /* Defined for backward compatability with project created prior to\r
49 FreeRTOS.org V4.3.0. */\r
50 #ifndef configKERNEL_INTERRUPT_PRIORITY\r
51         #define configKERNEL_INTERRUPT_PRIORITY 1\r
52 #endif\r
53 \r
54 /* Use _T1Interrupt as the interrupt handler name if the application writer has\r
55 not provided their own. */\r
56 #ifndef configTICK_INTERRUPT_HANDLER\r
57         #define configTICK_INTERRUPT_HANDLER _T1Interrupt\r
58 #endif /* configTICK_INTERRUPT_HANDLER */\r
59 \r
60 /* The program counter is only 23 bits. */\r
61 #define portUNUSED_PR_BITS      0x7f\r
62 \r
63 /* Records the nesting depth of calls to portENTER_CRITICAL(). */\r
64 UBaseType_t uxCriticalNesting = 0xef;\r
65 \r
66 #if configKERNEL_INTERRUPT_PRIORITY != 1\r
67         #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
68 #endif\r
69 \r
70 #if defined( __PIC24E__ ) || defined ( __PIC24F__ ) || defined( __PIC24FK__ ) || defined( __PIC24H__ )\r
71 \r
72     #ifdef __HAS_EDS__\r
73                 #define portRESTORE_CONTEXT()                                                                                                                                                                           \\r
74                                         asm volatile(   "MOV    _pxCurrentTCB, W0               \n"     /* Restore the stack pointer for the task. */           \\r
75                                                         "MOV    [W0], W15                               \n"                                                                                                                             \\r
76                                                         "POP    W0                                              \n"     /* Restore the critical nesting counter for the task. */        \\r
77                                                         "MOV    W0, _uxCriticalNesting  \n"                                                                                                                             \\r
78                                                         "POP    DSWPAG                                  \n"                                                                                                                             \\r
79                                                         "POP    DSRPAG                                  \n"                                                                                                                             \\r
80                                                         "POP    CORCON                                  \n"                                                                                                                             \\r
81                                                         "POP    TBLPAG                                  \n"                                                                                                                             \\r
82                                                         "POP    RCOUNT                                  \n"     /* Restore the registers from the stack. */                                     \\r
83                                                         "POP    W14                                             \n"                                                                                                                             \\r
84                                                         "POP.D  W12                                             \n"                                                                                                                             \\r
85                                                         "POP.D  W10                                             \n"                                                                                                                             \\r
86                                                         "POP.D  W8                                              \n"                                                                                                                             \\r
87                                                         "POP.D  W6                                              \n"                                                                                                                             \\r
88                                                         "POP.D  W4                                              \n"                                                                                                                             \\r
89                                                         "POP.D  W2                                              \n"                                                                                                                             \\r
90                                                         "POP.D  W0                                              \n"                                                                                                                             \\r
91                                                         "POP    SR                                                " );\r
92         #else /* __HAS_EDS__ */\r
93                 #define portRESTORE_CONTEXT()                                                                                                                                                                           \\r
94                         asm volatile(   "MOV    _pxCurrentTCB, W0               \n"     /* Restore the stack pointer for the task. */                           \\r
95                                                         "MOV    [W0], W15                               \n"                                                                                                                             \\r
96                                                         "POP    W0                                              \n"     /* Restore the critical nesting counter for the task. */        \\r
97                                                         "MOV    W0, _uxCriticalNesting  \n"                                                                                                                             \\r
98                                                         "POP    PSVPAG                                  \n"                                                                                                                             \\r
99                                                         "POP    CORCON                                  \n"                                                                                                                             \\r
100                                                         "POP    TBLPAG                                  \n"                                                                                                                             \\r
101                                                         "POP    RCOUNT                                  \n"     /* Restore the registers from the stack. */                                     \\r
102                                                         "POP    W14                                             \n"                                                                                                                             \\r
103                                                         "POP.D  W12                                             \n"                                                                                                                             \\r
104                                                         "POP.D  W10                                             \n"                                                                                                                             \\r
105                                                         "POP.D  W8                                              \n"                                                                                                                             \\r
106                                                         "POP.D  W6                                              \n"                                                                                                                             \\r
107                                                         "POP.D  W4                                              \n"                                                                                                                             \\r
108                                                         "POP.D  W2                                              \n"                                                                                                                             \\r
109                                                         "POP.D  W0                                              \n"                                                                                                                             \\r
110                                                         "POP    SR                                                " );\r
111                 #endif /* __HAS_EDS__ */\r
112 #endif /* MPLAB_PIC24_PORT */\r
113 \r
114 #if defined( __dsPIC30F__ ) || defined( __dsPIC33F__ )\r
115 \r
116         #define portRESTORE_CONTEXT()                                                                                                                                                                           \\r
117                 asm volatile(   "MOV    _pxCurrentTCB, W0               \n"     /* Restore the stack pointer for the task. */                           \\r
118                                                 "MOV    [W0], W15                               \n"                                                                                                                             \\r
119                                                 "POP    W0                                              \n"     /* Restore the critical nesting counter for the task. */        \\r
120                                                 "MOV    W0, _uxCriticalNesting  \n"                                                                                                                             \\r
121                                                 "POP    PSVPAG                                  \n"                                                                                                                             \\r
122                                                 "POP    CORCON                                  \n"                                                                                                                             \\r
123                                                 "POP    DOENDH                                  \n"                                                                                                                             \\r
124                                                 "POP    DOENDL                                  \n"                                                                                                                             \\r
125                                                 "POP    DOSTARTH                                \n"                                                                                                                             \\r
126                                                 "POP    DOSTARTL                                \n"                                                                                                                             \\r
127                                                 "POP    DCOUNT                                  \n"                                                                                                                             \\r
128                                                 "POP    ACCBU                                   \n"                                                                                                                             \\r
129                                                 "POP    ACCBH                                   \n"                                                                                                                             \\r
130                                                 "POP    ACCBL                                   \n"                                                                                                                             \\r
131                                                 "POP    ACCAU                                   \n"                                                                                                                             \\r
132                                                 "POP    ACCAH                                   \n"                                                                                                                             \\r
133                                                 "POP    ACCAL                                   \n"                                                                                                                             \\r
134                                                 "POP    TBLPAG                                  \n"                                                                                                                             \\r
135                                                 "POP    RCOUNT                                  \n"     /* Restore the registers from the stack. */                                     \\r
136                                                 "POP    W14                                             \n"                                                                                                                             \\r
137                                                 "POP.D  W12                                             \n"                                                                                                                             \\r
138                                                 "POP.D  W10                                             \n"                                                                                                                             \\r
139                                                 "POP.D  W8                                              \n"                                                                                                                             \\r
140                                                 "POP.D  W6                                              \n"                                                                                                                             \\r
141                                                 "POP.D  W4                                              \n"                                                                                                                             \\r
142                                                 "POP.D  W2                                              \n"                                                                                                                             \\r
143                                                 "POP.D  W0                                              \n"                                                                                                                             \\r
144                                                 "POP    SR                                                " );\r
145 \r
146 #endif /* MPLAB_DSPIC_PORT */\r
147 \r
148 #ifndef portRESTORE_CONTEXT\r
149         #error Unrecognised device selected\r
150 \r
151         /* Note:  dsPIC parts with EDS are not supported as there is no easy way to\r
152         recover the hardware stacked copies for DOCOUNT, DOHIGH, DOLOW. */\r
153 #endif\r
154 \r
155 /*\r
156  * Setup the timer used to generate the tick interrupt.\r
157  */\r
158 void vApplicationSetupTickTimerInterrupt( void );\r
159 \r
160 /*\r
161  * See header file for description.\r
162  */\r
163 StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )\r
164 {\r
165 uint16_t usCode;\r
166 UBaseType_t i;\r
167 \r
168 const StackType_t xInitialStack[] =\r
169 {\r
170         0x1111, /* W1 */\r
171         0x2222, /* W2 */\r
172         0x3333, /* W3 */\r
173         0x4444, /* W4 */\r
174         0x5555, /* W5 */\r
175         0x6666, /* W6 */\r
176         0x7777, /* W7 */\r
177         0x8888, /* W8 */\r
178         0x9999, /* W9 */\r
179         0xaaaa, /* W10 */\r
180         0xbbbb, /* W11 */\r
181         0xcccc, /* W12 */\r
182         0xdddd, /* W13 */\r
183         0xeeee, /* W14 */\r
184         0xcdce, /* RCOUNT */\r
185         0xabac, /* TBLPAG */\r
186 \r
187         /* dsPIC specific registers. */\r
188         #ifdef MPLAB_DSPIC_PORT\r
189                 0x0202, /* ACCAL */\r
190                 0x0303, /* ACCAH */\r
191                 0x0404, /* ACCAU */\r
192                 0x0505, /* ACCBL */\r
193                 0x0606, /* ACCBH */\r
194                 0x0707, /* ACCBU */\r
195                 0x0808, /* DCOUNT */\r
196                 0x090a, /* DOSTARTL */\r
197                 0x1010, /* DOSTARTH */\r
198                 0x1110, /* DOENDL */\r
199                 0x1212, /* DOENDH */\r
200         #endif\r
201 };\r
202 \r
203         /* Setup the stack as if a yield had occurred.\r
204 \r
205         Save the low bytes of the program counter. */\r
206         usCode = ( uint16_t ) pxCode;\r
207         *pxTopOfStack = ( StackType_t ) usCode;\r
208         pxTopOfStack++;\r
209 \r
210         /* Save the high byte of the program counter.  This will always be zero\r
211         here as it is passed in a 16bit pointer.  If the address is greater than\r
212         16 bits then the pointer will point to a jump table. */\r
213         *pxTopOfStack = ( StackType_t ) 0;\r
214         pxTopOfStack++;\r
215 \r
216         /* Status register with interrupts enabled. */\r
217         *pxTopOfStack = portINITIAL_SR;\r
218         pxTopOfStack++;\r
219 \r
220         /* Parameters are passed in W0. */\r
221         *pxTopOfStack = ( StackType_t ) pvParameters;\r
222         pxTopOfStack++;\r
223 \r
224         for( i = 0; i < ( sizeof( xInitialStack ) / sizeof( StackType_t ) ); i++ )\r
225         {\r
226                 *pxTopOfStack = xInitialStack[ i ];\r
227                 pxTopOfStack++;\r
228         }\r
229 \r
230         *pxTopOfStack = CORCON;\r
231         pxTopOfStack++;\r
232 \r
233         #if defined(__HAS_EDS__)\r
234                 *pxTopOfStack = DSRPAG;\r
235                 pxTopOfStack++;\r
236                 *pxTopOfStack = DSWPAG;\r
237                 pxTopOfStack++;\r
238         #else /* __HAS_EDS__ */\r
239                 *pxTopOfStack = PSVPAG;\r
240                 pxTopOfStack++;\r
241         #endif /* __HAS_EDS__ */\r
242 \r
243         /* Finally the critical nesting depth. */\r
244         *pxTopOfStack = 0x00;\r
245         pxTopOfStack++;\r
246 \r
247         return pxTopOfStack;\r
248 }\r
249 /*-----------------------------------------------------------*/\r
250 \r
251 BaseType_t xPortStartScheduler( void )\r
252 {\r
253         /* Setup a timer for the tick ISR. */\r
254         vApplicationSetupTickTimerInterrupt();\r
255 \r
256         /* Restore the context of the first task to run. */\r
257         portRESTORE_CONTEXT();\r
258 \r
259         /* Simulate the end of the yield function. */\r
260         asm volatile ( "return" );\r
261 \r
262         /* Should not reach here. */\r
263         return pdTRUE;\r
264 }\r
265 /*-----------------------------------------------------------*/\r
266 \r
267 void vPortEndScheduler( void )\r
268 {\r
269         /* Not implemented in ports where there is nothing to return to.\r
270         Artificially force an assert. */\r
271         configASSERT( uxCriticalNesting == 1000UL );\r
272 }\r
273 /*-----------------------------------------------------------*/\r
274 \r
275 /*\r
276  * Setup a timer for a regular tick.\r
277  */\r
278 __attribute__(( weak )) void vApplicationSetupTickTimerInterrupt( void )\r
279 {\r
280 const uint32_t ulCompareMatch = ( ( configCPU_CLOCK_HZ / portTIMER_PRESCALE ) / configTICK_RATE_HZ ) - 1;\r
281 \r
282         /* Prescale of 8. */\r
283         T1CON = 0;\r
284         TMR1 = 0;\r
285 \r
286         PR1 = ( uint16_t ) ulCompareMatch;\r
287 \r
288         /* Setup timer 1 interrupt priority. */\r
289         IPC0bits.T1IP = configKERNEL_INTERRUPT_PRIORITY;\r
290 \r
291         /* Clear the interrupt as a starting condition. */\r
292         IFS0bits.T1IF = 0;\r
293 \r
294         /* Enable the interrupt. */\r
295         IEC0bits.T1IE = 1;\r
296 \r
297         /* Setup the prescale value. */\r
298         T1CONbits.TCKPS0 = 1;\r
299         T1CONbits.TCKPS1 = 0;\r
300 \r
301         /* Start the timer. */\r
302         T1CONbits.TON = 1;\r
303 }\r
304 /*-----------------------------------------------------------*/\r
305 \r
306 void vPortEnterCritical( void )\r
307 {\r
308         portDISABLE_INTERRUPTS();\r
309         uxCriticalNesting++;\r
310 }\r
311 /*-----------------------------------------------------------*/\r
312 \r
313 void vPortExitCritical( void )\r
314 {\r
315         configASSERT( uxCriticalNesting );\r
316         uxCriticalNesting--;\r
317         if( uxCriticalNesting == 0 )\r
318         {\r
319                 portENABLE_INTERRUPTS();\r
320         }\r
321 }\r
322 /*-----------------------------------------------------------*/\r
323 \r
324 void __attribute__((__interrupt__, auto_psv)) configTICK_INTERRUPT_HANDLER( void )\r
325 {\r
326         /* Clear the timer interrupt. */\r
327         IFS0bits.T1IF = 0;\r
328 \r
329         if( xTaskIncrementTick() != pdFALSE )\r
330         {\r
331                 portYIELD();\r
332         }\r
333 }\r
334 \r