Skip to content

Commit 299385b

Browse files
committed
Merge pull request #1079 from stevew817/master
Add in Silicon Labs targets with asynchronous API support
2 parents 7c1fba2 + 35a4ba5 commit 299385b

File tree

449 files changed

+162292
-235
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

449 files changed

+162292
-235
lines changed

libraries/mbed/api/CThunk.h

Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
/* General C++ Object Thunking class
2+
*
3+
* - allows direct callbacks to non-static C++ class functions
4+
* - keeps track for the corresponding class instance
5+
* - supports an optional context parameter for the called function
6+
* - ideally suited for class object receiving interrupts (NVIC_SetVector)
7+
*
8+
* Copyright (c) 2014-2015 ARM Limited
9+
*
10+
* Licensed under the Apache License, Version 2.0 (the "License");
11+
* you may not use this file except in compliance with the License.
12+
* You may obtain a copy of the License at
13+
*
14+
* http://www.apache.org/licenses/LICENSE-2.0
15+
*
16+
* Unless required by applicable law or agreed to in writing, software
17+
* distributed under the License is distributed on an "AS IS" BASIS,
18+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19+
* See the License for the specific language governing permissions and
20+
* limitations under the License.
21+
*/
22+
#ifndef __CTHUNK_H__
23+
#define __CTHUNK_H__
24+
25+
#define CTHUNK_ADDRESS 1
26+
27+
#if defined(__CORTEX_M3) || defined(__CORTEX_M4) || defined(__thumb2__)
28+
#define CTHUNK_VARIABLES volatile uint32_t code[1]
29+
/**
30+
* CTHUNK disassembly for Cortex-M3/M4 (thumb2):
31+
* * ldm.w pc,{r0,r1,r2,pc}
32+
*
33+
* This instruction loads the arguments for the static thunking function to r0-r2, and
34+
* branches to that function by loading its address into PC.
35+
*
36+
* This is safe for both regular calling and interrupt calling, since it only touches scratch registers
37+
* which should be saved by the caller, and are automatically saved as part of the IRQ context switch.
38+
*/
39+
#define CTHUNK_ASSIGMENT m_thunk.code[0] = 0x8007E89F
40+
41+
#elif defined(__CORTEX_M0PLUS) || defined(__CORTEX_M0)
42+
/*
43+
* CTHUNK disassembly for Cortex M0 (thumb):
44+
* * push {r0,r1,r2,r3,r4,lr} save touched registers and return address
45+
* * movs r4,#4 set up address to load arguments from (immediately following this code block) (1)
46+
* * add r4,pc set up address to load arguments from (immediately following this code block) (2)
47+
* * ldm r4!,{r0,r1,r2,r3} load arguments for static thunk function
48+
* * blx r3 call static thunk function
49+
* * pop {r0,r1,r2,r3,r4,pc} restore scratch registers and return from function
50+
*/
51+
#define CTHUNK_VARIABLES volatile uint32_t code[3]
52+
#define CTHUNK_ASSIGMENT do { \
53+
m_thunk.code[0] = 0x2404B51F; \
54+
m_thunk.code[1] = 0xCC0F447C; \
55+
m_thunk.code[2] = 0xBD1F4798; \
56+
} while (0)
57+
58+
#else
59+
#error "Target is not currently suported."
60+
#endif
61+
62+
/* IRQ/Exception compatible thunk entry function */
63+
typedef void (*CThunkEntry)(void);
64+
65+
template<class T>
66+
class CThunk
67+
{
68+
public:
69+
typedef void (T::*CCallbackSimple)(void);
70+
typedef void (T::*CCallback)(void* context);
71+
72+
inline CThunk(T *instance)
73+
{
74+
init(instance, NULL, NULL);
75+
}
76+
77+
inline CThunk(T *instance, CCallback callback)
78+
{
79+
init(instance, callback, NULL);
80+
}
81+
82+
~CThunk() {
83+
84+
}
85+
86+
inline CThunk(T *instance, CCallbackSimple callback)
87+
{
88+
init(instance, (CCallback)callback, NULL);
89+
}
90+
91+
inline CThunk(T &instance, CCallback callback)
92+
{
93+
init(instance, callback, NULL);
94+
}
95+
96+
inline CThunk(T &instance, CCallbackSimple callback)
97+
{
98+
init(instance, (CCallback)callback, NULL);
99+
}
100+
101+
inline CThunk(T &instance, CCallback callback, void* context)
102+
{
103+
init(instance, callback, context);
104+
}
105+
106+
inline void callback(CCallback callback)
107+
{
108+
m_callback = callback;
109+
}
110+
111+
inline void callback(CCallbackSimple callback)
112+
{
113+
m_callback = (CCallback)callback;
114+
}
115+
116+
inline void context(void* context)
117+
{
118+
m_thunk.context = (uint32_t)context;
119+
}
120+
121+
inline void context(uint32_t context)
122+
{
123+
m_thunk.context = context;
124+
}
125+
126+
inline uint32_t entry(void)
127+
{
128+
return (((uint32_t)&m_thunk)|CTHUNK_ADDRESS);
129+
}
130+
131+
/* get thunk entry point for connecting rhunk to an IRQ table */
132+
inline operator CThunkEntry(void)
133+
{
134+
return (CThunkEntry)entry();
135+
}
136+
137+
/* get thunk entry point for connecting rhunk to an IRQ table */
138+
inline operator uint32_t(void)
139+
{
140+
return entry();
141+
}
142+
143+
/* simple test function */
144+
inline void call(void)
145+
{
146+
(((CThunkEntry)(entry()))());
147+
}
148+
149+
private:
150+
T* m_instance;
151+
volatile CCallback m_callback;
152+
153+
// TODO: this needs proper fix, to refactor toolchain header file and all its use
154+
// PACKED there is not defined properly for IAR
155+
#if defined (__ICCARM__)
156+
typedef __packed struct
157+
{
158+
CTHUNK_VARIABLES;
159+
volatile uint32_t instance;
160+
volatile uint32_t context;
161+
volatile uint32_t callback;
162+
volatile uint32_t trampoline;
163+
} CThunkTrampoline;
164+
#else
165+
typedef struct
166+
{
167+
CTHUNK_VARIABLES;
168+
volatile uint32_t instance;
169+
volatile uint32_t context;
170+
volatile uint32_t callback;
171+
volatile uint32_t trampoline;
172+
} __attribute__((__packed__)) CThunkTrampoline;
173+
#endif
174+
175+
static void trampoline(T* instance, void* context, CCallback* callback)
176+
{
177+
if(instance && *callback) {
178+
(static_cast<T*>(instance)->**callback)(context);
179+
}
180+
}
181+
182+
volatile CThunkTrampoline m_thunk;
183+
184+
inline void init(T *instance, CCallback callback, void* context)
185+
{
186+
/* remember callback - need to add this level of redirection
187+
as pointer size for member functions differs between platforms */
188+
m_callback = callback;
189+
190+
/* populate thunking trampoline */
191+
CTHUNK_ASSIGMENT;
192+
m_thunk.context = (uint32_t)context;
193+
m_thunk.instance = (uint32_t)instance;
194+
m_thunk.callback = (uint32_t)&m_callback;
195+
m_thunk.trampoline = (uint32_t)&trampoline;
196+
197+
__ISB();
198+
__DSB();
199+
}
200+
};
201+
202+
#endif/*__CTHUNK_H__*/

libraries/mbed/api/CircularBuffer.h

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/* mbed Microcontroller Library
2+
* Copyright (c) 2015 ARM Limited
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+
#ifndef MBED_CIRCULARBUFFER_H
17+
#define MBED_CIRCULARBUFFER_H
18+
19+
namespace mbed {
20+
21+
/** Templated Circular buffer class
22+
*/
23+
template<typename T, uint32_t BufferSize, typename CounterType = uint32_t>
24+
class CircularBuffer {
25+
public:
26+
CircularBuffer() : _head(0), _tail(0), _full(false) {
27+
}
28+
29+
~CircularBuffer() {
30+
}
31+
32+
/** Push the transaction to the buffer. This overwrites the buffer if it's
33+
* full
34+
*
35+
* @param data Data to be pushed to the buffer
36+
*/
37+
void push(const T& data) {
38+
if (full()) {
39+
_tail++;
40+
_tail %= BufferSize;
41+
}
42+
_pool[_head++] = data;
43+
_head %= BufferSize;
44+
if (_head == _tail) {
45+
_full = true;
46+
}
47+
}
48+
49+
/** Pop the transaction from the buffer
50+
*
51+
* @param data Data to be pushed to the buffer
52+
* @return True if the buffer is not empty and data contains a transaction, false otherwise
53+
*/
54+
bool pop(T& data) {
55+
if (!empty()) {
56+
data = _pool[_tail++];
57+
_tail %= BufferSize;
58+
_full = false;
59+
return true;
60+
}
61+
return false;
62+
}
63+
64+
/** Check if the buffer is empty
65+
*
66+
* @return True if the buffer is empty, false if not
67+
*/
68+
bool empty() {
69+
return (_head == _tail) && !_full;
70+
}
71+
72+
/** Check if the buffer is full
73+
*
74+
* @return True if the buffer is full, false if not
75+
*/
76+
bool full() {
77+
return _full;
78+
}
79+
80+
/** Reset the buffer
81+
*
82+
*/
83+
void reset() {
84+
_head = 0;
85+
_tail = 0;
86+
_full = false;
87+
}
88+
89+
private:
90+
T _pool[BufferSize];
91+
CounterType _head;
92+
CounterType _tail;
93+
bool _full;
94+
};
95+
96+
}
97+
98+
#endif

0 commit comments

Comments
 (0)