aboutsummaryrefslogtreecommitdiff
path: root/lib/chibios-contrib/os/common/ports/MSP430X/chcore.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/chibios-contrib/os/common/ports/MSP430X/chcore.h')
-rw-r--r--lib/chibios-contrib/os/common/ports/MSP430X/chcore.h443
1 files changed, 443 insertions, 0 deletions
diff --git a/lib/chibios-contrib/os/common/ports/MSP430X/chcore.h b/lib/chibios-contrib/os/common/ports/MSP430X/chcore.h
new file mode 100644
index 000000000..7776e9f93
--- /dev/null
+++ b/lib/chibios-contrib/os/common/ports/MSP430X/chcore.h
@@ -0,0 +1,443 @@
1/*
2 ChibiOS/HAL - Copyright (C) 2016 Andrew Wygle aka awygle
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15*/
16
17/**
18 * @file MSP430X/nilcore.h
19 * @brief MSP430X port macros and structures.
20 *
21 * @addtogroup MSP430X_CORE
22 * @{
23 */
24
25#ifndef CHCORE_H
26#define CHCORE_H
27
28#include <msp430.h>
29#include <in430.h>
30
31extern bool __msp430x_in_isr;
32
33/*===========================================================================*/
34/* Module constants. */
35/*===========================================================================*/
36
37/**
38 * @name Architecture and Compiler
39 * @{
40 */
41/**
42 * @brief Macro defining the port architecture.
43 */
44#define PORT_ARCHITECTURE_MSP430X
45
46/**
47 * @brief Name of the implemented architecture.
48 */
49#define PORT_ARCHITECTURE_NAME "MSP430X"
50
51/**
52 * @brief Name of the architecture variant.
53 */
54#define PORT_CORE_VARIANT_NAME "MSP430Xv2"
55
56/* The following code is not processed when the file is included from an
57 * asm module because those intrinsic macrosa re not necessarily defined
58 * by the assembler too.*/
59#if !defined(_FROM_ASM_)
60
61/**
62 * @brief Compiler name and version.
63 */
64#if defined(__GNUC__) || defined(__DOXYGEN__)
65#define PORT_COMPILER_NAME "GCC " __VERSION__
66
67#else
68#error "unsupported compiler"
69#endif
70
71#endif /* !defined(_FROM_ASM_) */
72/**
73 * @brief Port-specific information string.
74 */
75#define PORT_INFO "16 bits code addressing"
76
77/**
78 * @brief This port supports a realtime counter.
79 */
80#define PORT_SUPPORTS_RT FALSE
81/** @} */
82
83/*===========================================================================*/
84/* Module pre-compile time settings. */
85/*===========================================================================*/
86
87/**
88 * @brief Stack size for the system idle thread.
89 * @details This size depends on the idle thread implementation, usually
90 * the idle thread should take no more space than those reserved
91 * by @p PORT_INT_REQUIRED_STACK.
92 * @note In this port it is set to 8.
93 */
94#if !defined(PORT_IDLE_THREAD_STACK_SIZE) || defined(__DOXYGEN__)
95#define PORT_IDLE_THREAD_STACK_SIZE 8
96#endif
97
98/**
99 * @brief Per-thread stack overhead for interrupts servicing.
100 * @details This constant is used in the calculation of the correct working
101 * area size.
102 * @note In this port the default is 32 bytes per thread.
103 */
104#if !defined(PORT_INT_REQUIRED_STACK) || defined(__DOXYGEN__)
105#define PORT_INT_REQUIRED_STACK 32
106#endif
107
108/**
109 * @brief Enables an alternative timer implementation.
110 * @details Usually the port uses a timer interface defined in the file
111 * @p nilcore_timer.h, if this option is enabled then the file
112 * @p nilcore_timer_alt.h is included instead.
113 */
114#if !defined(PORT_USE_ALT_TIMER)
115#define PORT_USE_ALT_TIMER FALSE
116#endif
117
118/*===========================================================================*/
119/* Derived constants and error checks. */
120/*===========================================================================*/
121
122/*===========================================================================*/
123/* Module data structures and types. */
124/*===========================================================================*/
125
126/* The following code is not processed when the file is included from an
127 asm module.*/
128#if !defined(_FROM_ASM_)
129
130/**
131 * @brief Type of stack and memory alignment enforcement.
132 */
133typedef uint16_t stkalign_t;
134
135/**
136 * @brief Type of natural register size - depends on memory model.
137 */
138#if defined(__MSP430X_LARGE__)
139typedef unsigned __int20 reg_t;
140#else
141typedef uint16_t reg_t;
142#endif
143
144/**
145 * @brief Natural alignment constant.
146 * @note It is the minimum alignment for pointer-size variables.
147 */
148#define PORT_NATURAL_ALIGN 2U
149
150/**
151 * @brief Stack alignment constant.
152 * @note It is the alignement required for the stack pointer.
153 */
154#define PORT_STACK_ALIGN 2U
155
156/**
157 * @brief Working Areas alignment constant.
158 * @note It is the alignment to be enforced for thread working areas.
159 */
160#define PORT_WORKING_AREA_ALIGN 2U
161/** @} */
162
163/**
164 * @brief System saved context.
165 * @details This structure represents the inner stack frame during a context
166 * switching.
167 */
168struct port_intctx {
169 reg_t r4;
170 reg_t r5;
171 reg_t r6;
172 reg_t r7;
173 reg_t r8;
174 reg_t r9;
175 reg_t r10;
176 reg_t r0; /* program counter */
177};
178
179/**
180 * @brief Platform dependent part of the @p thread_t structure.
181 * @details This structure usually contains just the saved stack pointer
182 * defined as a pointer to a @p port_intctx structure.
183 */
184struct port_context {
185 struct port_intctx *sp;
186};
187
188#endif /* !defined(_FROM_ASM_) */
189
190/*===========================================================================*/
191/* Module macros. */
192/*===========================================================================*/
193
194/**
195 * @brief Platform dependent thread stack setup.
196 * @details This code usually setup the context switching frame represented
197 * by an @p port_intctx structure.
198 */
199#define PORT_SETUP_CONTEXT(tp, wbase, wtop, pf, arg) { \
200 (tp)->ctx.sp = (struct port_intctx*)(((uint8_t *)(wtop)) - \
201 sizeof(struct port_intctx)); \
202 (tp)->ctx.sp->r4 = (reg_t)pf; \
203 (tp)->ctx.sp->r5 = (reg_t)arg; \
204 (tp)->ctx.sp->r0 = (reg_t)_port_thread_start; \
205}
206
207/**
208 * @brief Static working area allocation.
209 * @details This macro is used to allocate a static thread working area
210 * aligned as both position and size.
211 *
212 * @param[in] s the name to be assigned to the stack array
213 * @param[in] n the stack size to be assigned to the thread
214 */
215#define PORT_WORKING_AREA(s, n) \
216 stkalign_t s[THD_WORKING_AREA_SIZE(n) / sizeof (stkalign_t)]
217
218/**
219 * @brief Computes the thread working area global size.
220 * @note There is no need to perform alignments in this macro.
221 */
222#define PORT_WA_SIZE(n) ((sizeof(struct port_intctx) - 1) + \
223 (n) + (PORT_INT_REQUIRED_STACK))
224
225/**
226 * @brief IRQ prologue code.
227 * @details This macro must be inserted at the start of all IRQ handlers
228 * enabled to invoke system APIs.
229 */
230#define PORT_IRQ_PROLOGUE() __msp430x_in_isr = true;
231
232/**
233 * @brief IRQ epilogue code.
234 * @details This macro must be inserted at the end of all IRQ handlers
235 * enabled to invoke system APIs.
236 */
237#define PORT_IRQ_EPILOGUE() { \
238 __msp430x_in_isr = false; \
239 _dbg_check_lock(); \
240 if (chSchIsPreemptionRequired()) \
241 chSchDoReschedule(); \
242 _dbg_check_unlock(); \
243}
244
245/**
246 * @brief IRQ handler function declaration.
247 * @note @p id can be a function name or a vector number depending on the
248 * port implementation.
249 */
250#define PORT_IRQ_HANDLER(id) __attribute__ ((interrupt(id))) \
251 void ISR_ ## id (void)
252
253/**
254 * @brief Fast IRQ handler function declaration.
255 * @note @p id can be a function name or a vector number depending on the
256 * port implementation.
257 */
258#define PORT_FAST_IRQ_HANDLER(id) PORT_IRQ_HANDLER(id)
259
260/**
261 * @brief Performs a context switch between two threads.
262 * @details This is the most critical code in any port, this function
263 * is responsible for the context switch between 2 threads.
264 * @note The implementation of this code affects <b>directly</b> the context
265 * switch performance so optimize here as much as you can.
266 *
267 * @param[in] ntp the thread to be switched in
268 * @param[in] otp the thread to be switched out
269 */
270#define port_switch(ntp, otp) _port_switch(ntp, otp)
271
272/*===========================================================================*/
273/* External declarations. */
274/*===========================================================================*/
275
276/* The following code is not processed when the file is included from an
277 asm module.*/
278#if !defined(_FROM_ASM_)
279
280#ifdef __cplusplus
281extern "C" {
282#endif
283 void _port_irq_epilogue(void);
284 void _port_switch(thread_t *ntp, thread_t *otp);
285 void _port_thread_start(void);
286#ifdef __cplusplus
287}
288#endif
289
290#endif /* !defined(_FROM_ASM_) */
291
292/*===========================================================================*/
293/* Module inline functions. */
294/*===========================================================================*/
295
296/* The following code is not processed when the file is included from an
297 asm module.*/
298#if !defined(_FROM_ASM_)
299
300/**
301 * @brief Port-related initialization code.
302 */
303static inline void port_init(void) {
304 __msp430x_in_isr = false;
305}
306
307/**
308 * @brief Returns a word encoding the current interrupts status.
309 *
310 * @return The interrupts status.
311 */
312static inline syssts_t port_get_irq_status(void) {
313
314 return __get_SR_register();
315}
316
317/**
318 * @brief Checks the interrupt status.
319 *
320 * @param[in] sts the interrupt status word
321 *
322 * @return The interrupt status.
323 * @retvel false the word specified a disabled interrupts status.
324 * @retvel true the word specified an enabled interrupts status.
325 */
326static inline bool port_irq_enabled(syssts_t sts) {
327
328 return sts & GIE;
329}
330
331/**
332 * @brief Determines the current execution context.
333 *
334 * @return The execution context.
335 * @retval false not running in ISR mode.
336 * @retval true running in ISR mode.
337 */
338static inline bool port_is_isr_context(void) {
339 return __msp430x_in_isr;
340}
341
342/**
343 * @brief Kernel-lock action.
344 */
345static inline void port_lock(void) {
346
347 _disable_interrupts();
348 asm volatile("nop");
349}
350
351/**
352 * @brief Kernel-unlock action.
353 */
354static inline void port_unlock(void) {
355 asm volatile("nop");
356 _enable_interrupts();
357}
358
359/**
360 * @brief Kernel-lock action from an interrupt handler.
361 * @note This function is empty in this port.
362 */
363static inline void port_lock_from_isr(void) {
364
365}
366
367/**
368 * @brief Kernel-unlock action from an interrupt handler.
369 * @note This function is empty in this port.
370 */
371static inline void port_unlock_from_isr(void) {
372
373}
374
375/**
376 * @brief Disables all the interrupt sources.
377 */
378static inline void port_disable(void) {
379
380 _disable_interrupts();
381 asm volatile("nop");
382}
383
384/**
385 * @brief Disables the interrupt sources below kernel-level priority.
386 */
387static inline void port_suspend(void) {
388
389 _disable_interrupts();
390 asm volatile("nop");
391}
392
393/**
394 * @brief Enables all the interrupt sources.
395 */
396static inline void port_enable(void) {
397
398 asm volatile("nop");
399 _enable_interrupts();
400}
401
402/**
403 * @brief Enters an architecture-dependent IRQ-waiting mode.
404 * @details The function is meant to return when an interrupt becomes pending.
405 * The simplest implementation is an empty function or macro but this
406 * would not take advantage of architecture-specific power saving
407 * modes.
408 */
409static inline void port_wait_for_interrupt(void) {
410
411}
412
413/**
414 * @brief Returns the current value of the realtime counter.
415 *
416 * @return The realtime counter value.
417 */
418static inline rtcnt_t port_rt_get_counter_value(void) {
419 /* TODO implement realtime counter */
420 return 0;
421}
422
423#endif /* !defined(_FROM_ASM_) */
424
425/*===========================================================================*/
426/* Module late inclusions. */
427/*===========================================================================*/
428
429#if !defined(_FROM_ASM_)
430
431#if CH_CFG_ST_TIMEDELTA > 0
432#if !PORT_USE_ALT_TIMER
433#include "chcore_timer.h"
434#else /* PORT_USE_ALT_TIMER */
435#include "chcore_timer_alt.h"
436#endif /* PORT_USE_ALT_TIMER */
437#endif /* CH_CFG_ST_TIMEDELTA > 0 */
438
439#endif /* !defined(_FROM_ASM_) */
440
441#endif /* CHCORE_H */
442
443/** @} */