1 /*
2  * FreeRTOS Kernel V10.6.2
3  * Copyright (C) 2021 Amazon.com, Inc. or its affiliates.  All Rights Reserved.
4  *
5  * SPDX-License-Identifier: MIT
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy of
8  * this software and associated documentation files (the "Software"), to deal in
9  * the Software without restriction, including without limitation the rights to
10  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
11  * the Software, and to permit persons to whom the Software is furnished to do so,
12  * subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in all
15  * copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
19  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
20  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  *
24  * https://www.FreeRTOS.org
25  * https://github.com/FreeRTOS
26  *
27  */
28 
29 
30 #ifndef PORTMACRO_H
31 #define PORTMACRO_H
32 
33 /* *INDENT-OFF* */
34 #ifdef __cplusplus
35     extern "C" {
36 #endif
37 /* *INDENT-ON* */
38 
39 /*-----------------------------------------------------------
40  * Port specific definitions.
41  *
42  * The settings in this file configure FreeRTOS correctly for the
43  * given hardware and compiler.
44  *
45  * These settings should not be altered.
46  *-----------------------------------------------------------
47  */
48 
49 /* Type definitions. */
50 #define portCHAR        char
51 #define portFLOAT       float
52 #define portDOUBLE      double
53 #define portLONG        long
54 #define portSHORT       short
55 #define portSTACK_TYPE  uint8_t
56 #define portBASE_TYPE   char
57 
58 typedef portSTACK_TYPE StackType_t;
59 typedef signed char BaseType_t;
60 typedef unsigned char UBaseType_t;
61 
62 
63 #if( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_16_BITS )
64     typedef uint16_t TickType_t;
65     #define portMAX_DELAY ( TickType_t ) 0xffff
66 #elif ( configTICK_TYPE_WIDTH_IN_BITS == TICK_TYPE_WIDTH_32_BITS )
67     typedef uint32_t TickType_t;
68     #define portMAX_DELAY ( TickType_t )    ( 0xFFFFFFFFUL )
69 #else
70     #error configTICK_TYPE_WIDTH_IN_BITS set to unsupported tick type width.
71 #endif
72 /*-----------------------------------------------------------*/
73 
74 /* Hardware specifics. */
75 #define portBYTE_ALIGNMENT          1
76 #define portSTACK_GROWTH            ( -1 )
77 #define portTICK_PERIOD_MS          ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
78 #define portYIELD()                 __asm( "swi" );
79 /*-----------------------------------------------------------*/
80 
81 /* Critical section handling. */
82 #define portENABLE_INTERRUPTS()             __asm( "cli" )
83 #define portDISABLE_INTERRUPTS()            __asm( "sei" )
84 
85 /*
86  * Disable interrupts before incrementing the count of critical section nesting.
87  * The nesting count is maintained so we know when interrupts should be
88  * re-enabled.  Once interrupts are disabled the nesting count can be accessed
89  * directly.  Each task maintains its own nesting count.
90  */
91 #define portENTER_CRITICAL()                                    \
92 {                                                               \
93     extern volatile UBaseType_t uxCriticalNesting;  \
94                                                                 \
95     portDISABLE_INTERRUPTS();                                   \
96     uxCriticalNesting++;                                        \
97 }
98 
99 /*
100  * Interrupts are disabled so we can access the nesting count directly.  If the
101  * nesting is found to be 0 (no nesting) then we are leaving the critical
102  * section and interrupts can be re-enabled.
103  */
104 #define  portEXIT_CRITICAL()                                    \
105 {                                                               \
106     extern volatile UBaseType_t uxCriticalNesting;  \
107                                                                 \
108     uxCriticalNesting--;                                        \
109     if( uxCriticalNesting == 0 )                                \
110     {                                                           \
111         portENABLE_INTERRUPTS();                                \
112     }                                                           \
113 }
114 /*-----------------------------------------------------------*/
115 
116 /* Task utilities. */
117 
118 /*
119  * These macros are very simple as the processor automatically saves and
120  * restores its registers as interrupts are entered and exited.  In
121  * addition to the (automatically stacked) registers we also stack the
122  * critical nesting count.  Each task maintains its own critical nesting
123  * count as it is legitimate for a task to yield from within a critical
124  * section.  If the banked memory model is being used then the PPAGE
125  * register is also stored as part of the tasks context.
126  */
127 
128 #ifdef BANKED_MODEL
129     /*
130      * Load the stack pointer for the task, then pull the critical nesting
131      * count and PPAGE register from the stack.  The remains of the
132      * context are restored by the RTI instruction.
133      */
134     #define portRESTORE_CONTEXT()                           \
135     {                                       \
136         __asm( "                                \n\
137         .globl pxCurrentTCB         ; void *            \n\
138         .globl uxCriticalNesting        ; char              \n\
139                                             \n\
140         ldx  pxCurrentTCB                           \n\
141         lds  0,x                ; Stack             \n\
142                                             \n\
143         movb 1,sp+,uxCriticalNesting                        \n\
144         movb 1,sp+,0x30             ; PPAGE             \n\
145         " );                                    \
146     }
147 
148     /*
149      * By the time this macro is called the processor has already stacked the
150      * registers.  Simply stack the nesting count and PPAGE value, then save
151      * the task stack pointer.
152      */
153     #define portSAVE_CONTEXT()                          \
154     {                                       \
155         __asm( "                                \n\
156         .globl pxCurrentTCB         ; void *            \n\
157         .globl uxCriticalNesting        ; char              \n\
158                                             \n\
159         movb 0x30, 1,-sp            ; PPAGE             \n\
160         movb uxCriticalNesting, 1,-sp                       \n\
161                                             \n\
162         ldx  pxCurrentTCB                           \n\
163         sts  0,x                ; Stack             \n\
164         " );                                    \
165     }
166 #else
167 
168     /*
169      * These macros are as per the BANKED versions above, but without saving
170      * and restoring the PPAGE register.
171      */
172 
173     #define portRESTORE_CONTEXT()                           \
174     {                                       \
175         __asm( "                                \n\
176         .globl pxCurrentTCB         ; void *            \n\
177         .globl uxCriticalNesting        ; char              \n\
178                                             \n\
179         ldx  pxCurrentTCB                           \n\
180         lds  0,x                ; Stack             \n\
181                                             \n\
182         movb 1,sp+,uxCriticalNesting                        \n\
183         " );                                    \
184     }
185 
186     #define portSAVE_CONTEXT()                          \
187     {                                       \
188         __asm( "                                \n\
189         .globl pxCurrentTCB         ; void *            \n\
190         .globl uxCriticalNesting        ; char              \n\
191                                             \n\
192         movb uxCriticalNesting, 1,-sp                       \n\
193                                             \n\
194         ldx  pxCurrentTCB                           \n\
195         sts  0,x                ; Stack             \n\
196         " );                                    \
197     }
198 #endif
199 
200 /*
201  * Utility macros to save/restore correct software registers for GCC. This is
202  * useful when GCC does not generate appropriate ISR head/tail code.
203  */
204 #define portISR_HEAD()                                  \
205 {                                           \
206         __asm("                                 \n\
207         movw _.frame, 2,-sp                         \n\
208         movw _.tmp, 2,-sp                           \n\
209         movw _.z, 2,-sp                             \n\
210         movw _.xy, 2,-sp                            \n\
211         ;movw _.d2, 2,-sp                           \n\
212         ;movw _.d1, 2,-sp                           \n\
213         ");                                 \
214 }
215 
216 #define portISR_TAIL()                                  \
217 {                                           \
218         __asm("                                 \n\
219         movw 2,sp+, _.xy                            \n\
220         movw 2,sp+, _.z                             \n\
221         movw 2,sp+, _.tmp                           \n\
222         movw 2,sp+, _.frame                         \n\
223         ;movw 2,sp+, _.d1                           \n\
224         ;movw 2,sp+, _.d2                           \n\
225         rti                                 \n\
226         ");                                 \
227 }
228 
229 /*
230  * Utility macro to call macros above in correct order in order to perform a
231  * task switch from within a standard ISR.  This macro can only be used if
232  * the ISR does not use any local (stack) variables.  If the ISR uses stack
233  * variables portYIELD() should be used in it's place.
234  */
235 
236 #define portTASK_SWITCH_FROM_ISR()                              \
237     portSAVE_CONTEXT();                                         \
238     vTaskSwitchContext();                                       \
239     portRESTORE_CONTEXT();
240 
241 
242 /* Task function macros as described on the FreeRTOS.org WEB site. */
243 #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
244 #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
245 
246 /* *INDENT-OFF* */
247 #ifdef __cplusplus
248     }
249 #endif
250 /* *INDENT-ON* */
251 
252 #endif /* PORTMACRO_H */
253