MacroRat / MouseCode

Dependencies:   ITG3200 QEI

Committer:
sahilmgandhi
Date:
Sat May 27 03:37:24 2017 +0000
Revision:
37:3dcc95e9321c
Parent:
18:6a4db94011d3
Need to get centered more before turns (so after moving forward). Also fix when both walls are missing!

Who changed what in which revision?

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