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