PokittoLib is the library needed for programming the Pokitto DIY game console (www.pokitto.com)

Dependents:   YATTT sd_map_test cPong SnowDemo ... more

PokittoLib

Library for programming Pokitto hardware

How to Use

  1. Import this library to online compiler (see button "import" on the right hand side
  2. DO NOT import mbed-src anymore, a better version is now included inside PokittoLib
  3. Change My_settings.h according to your project
  4. Start coding!
Committer:
Pokitto
Date:
Wed Dec 25 23:59:52 2019 +0000
Revision:
71:531419862202
Parent:
5:ea7377f3d1af
Changed Mode2 C++ refresh code (graphical errors)

Who changed what in which revision?

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