Mark3 Realtime Kernel
threadport.h
Go to the documentation of this file.
1
/*===========================================================================
2
_____ _____ _____ _____
3
___| _|__ __|_ |__ __|__ |__ __| __ |__ ______
4
| \ / | || \ || | || |/ / ||___ |
5
| \/ | || \ || \ || \ ||___ |
6
|__/\__/|__|_||__|\__\ __||__|\__\ __||__|\__\ __||______|
7
|_____| |_____| |_____| |_____|
8
9
--[Mark3 Realtime Platform]--------------------------------------------------
10
11
Copyright (c) 2012 - 2019 m0slevin, all rights reserved.
12
See license.txt for more information
13
=========================================================================== */
20
#pragma once
21
22
#include "
portcfg.h
"
23
#include "
kerneltypes.h
"
24
25
#include <avr/io.h>
26
#include <avr/interrupt.h>
27
28
namespace
Mark3
29
{
30
// clang-format off
31
//---------------------------------------------------------------------------
32
#define ASM(x) asm volatile(x);
33
34
//---------------------------------------------------------------------------
36
#define PORT_TOP_OF_STACK(x, y) (reinterpret_cast<K_WORD*>(reinterpret_cast<K_ADDR>(x) + (static_cast<K_ADDR>(y) - 1)))
37
#define PORT_PUSH_TO_STACK(x, y) *x = y; x--;
39
40
//---------------------------------------------------------------------------
42
#define Thread_SaveContext() \
43
ASM("push r0"); \
44
ASM("in r0, __SREG__"); \
45
ASM("cli"); \
46
ASM("push r0"); \
47
ASM("push r1"); \
48
ASM("clr r1"); \
49
ASM("push r2"); \
50
ASM("push r3"); \
51
ASM("push r4"); \
52
ASM("push r5"); \
53
ASM("push r6"); \
54
ASM("push r7"); \
55
ASM("push r8"); \
56
ASM("push r9"); \
57
ASM("push r10"); \
58
ASM("push r11"); \
59
ASM("push r12"); \
60
ASM("push r13"); \
61
ASM("push r14"); \
62
ASM("push r15"); \
63
ASM("push r16"); \
64
ASM("push r17"); \
65
ASM("push r18"); \
66
ASM("push r19"); \
67
ASM("push r20"); \
68
ASM("push r21"); \
69
ASM("push r22"); \
70
ASM("push r23"); \
71
ASM("push r24"); \
72
ASM("push r25"); \
73
ASM("push r26"); \
74
ASM("push r27"); \
75
ASM("push r28"); \
76
ASM("push r29"); \
77
ASM("push r30"); \
78
ASM("push r31"); \
79
ASM("in r0, 0x3B"); \
80
ASM("push r0"); \
81
ASM("lds r26, g_pclCurrent"); \
82
ASM("lds r27, g_pclCurrent + 1"); \
83
ASM("adiw r26, 4"); \
84
ASM("in r0, 0x3D"); \
85
ASM("st x+, r0"); \
86
ASM("in r0, 0x3E"); \
87
ASM("st x+, r0");
88
89
//---------------------------------------------------------------------------
91
#define Thread_RestoreContext() \
92
ASM("lds r26, g_pclCurrent"); \
93
ASM("lds r27, g_pclCurrent + 1");\
94
ASM("adiw r26, 4"); \
95
ASM("ld r28, x+"); \
96
ASM("out 0x3D, r28"); \
97
ASM("ld r29, x+"); \
98
ASM("out 0x3E, r29"); \
99
ASM("pop r0"); \
100
ASM("out 0x3B, r0"); \
101
ASM("pop r31"); \
102
ASM("pop r30"); \
103
ASM("pop r29"); \
104
ASM("pop r28"); \
105
ASM("pop r27"); \
106
ASM("pop r26"); \
107
ASM("pop r25"); \
108
ASM("pop r24"); \
109
ASM("pop r23"); \
110
ASM("pop r22"); \
111
ASM("pop r21"); \
112
ASM("pop r20"); \
113
ASM("pop r19"); \
114
ASM("pop r18"); \
115
ASM("pop r17"); \
116
ASM("pop r16"); \
117
ASM("pop r15"); \
118
ASM("pop r14"); \
119
ASM("pop r13"); \
120
ASM("pop r12"); \
121
ASM("pop r11"); \
122
ASM("pop r10"); \
123
ASM("pop r9"); \
124
ASM("pop r8"); \
125
ASM("pop r7"); \
126
ASM("pop r6"); \
127
ASM("pop r5"); \
128
ASM("pop r4"); \
129
ASM("pop r3"); \
130
ASM("pop r2"); \
131
ASM("pop r1"); \
132
ASM("pop r0"); \
133
ASM("out __SREG__, r0"); \
134
ASM("pop r0");
135
136
//---------------------------------------------------------------------------
137
static
constexpr
auto
SR_
= uint8_t{0x3F};
138
extern
"C"
{
139
extern
K_WORD
g_kwSFR
;
140
extern
K_WORD
g_kwCriticalCount
;
141
}
142
143
//---------------------------------------------------------------------------
144
inline
uint8_t
PORT_CLZ
(uint8_t in_)
145
{
146
static
const
uint8_t u8Lookup[] = {4, 3, 2, 2, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0};
147
uint8_t hi = __builtin_avr_swap(in_) & 0x0F;
148
if
(hi) {
149
return
u8Lookup[hi];
150
}
151
return
4 + u8Lookup[in_];
152
}
153
154
//---------------------------------------------------------------------------
155
inline
void
PORT_IRQ_ENABLE
()
156
{
157
ASM
(
"sei"
);
158
}
159
160
//---------------------------------------------------------------------------
161
inline
void
PORT_IRQ_DISABLE
()
162
{
163
ASM
(
"cli"
);
164
}
165
166
//---------------------------------------------------------------------------
167
inline
void
PORT_CS_ENTER
()
168
{
169
auto
u8SFR = _SFR_IO8(SR_);
170
ASM
(
"cli"
);
171
if
(!
g_kwCriticalCount
) {
172
g_kwSFR
= u8SFR;
173
}
174
g_kwCriticalCount
++;
175
}
176
177
//---------------------------------------------------------------------------
178
inline
void
PORT_CS_EXIT
()
179
{
180
g_kwCriticalCount
--;
181
if
(!
g_kwCriticalCount
) {
182
_SFR_IO8(SR_) =
g_kwSFR
;
183
}
184
}
185
186
//---------------------------------------------------------------------------
187
inline
K_WORD
PORT_CS_NESTING
()
188
{
189
return
g_kwCriticalCount
;
190
}
191
}
// namespace Mark3
K_WORD
#define K_WORD
Size of a data word.
Definition:
portcfg.h:62
kerneltypes.h
Basic data type primatives used throughout the OS.
Mark3::SR_
static constexpr auto SR_
Definition:
threadport.h:137
Mark3::g_kwCriticalCount
K_WORD g_kwCriticalCount
Definition:
threadport.cpp:36
Mark3::PORT_CS_ENTER
void PORT_CS_ENTER()
Definition:
threadport.h:167
Mark3
Definition:
atomic.cpp:23
Mark3::g_kwSFR
K_WORD g_kwSFR
Definition:
threadport.cpp:35
Mark3::PORT_CLZ
uint8_t PORT_CLZ(uint8_t in_)
Definition:
threadport.h:144
Mark3::PORT_CS_EXIT
void PORT_CS_EXIT()
Definition:
threadport.h:178
portcfg.h
Mark3 Port Configuration.
Mark3::PORT_IRQ_ENABLE
void PORT_IRQ_ENABLE()
Definition:
threadport.h:155
Mark3::PORT_IRQ_DISABLE
void PORT_IRQ_DISABLE()
Definition:
threadport.h:161
ASM
#define ASM(x)
Definition:
threadport.h:32
Mark3::PORT_CS_NESTING
K_WORD PORT_CS_NESTING()
Definition:
threadport.h:187
kernel
src
arch
avr
atmega1284p
gcc
public
threadport.h
Generated on Tue Dec 3 2019 20:59:29 for Mark3 Realtime Kernel by
1.8.13