Color Oled(SSD1331) connect to STMicroelectronics Nucleo-F466

Dependencies:   ssd1331

Committer:
kadonotakashi
Date:
Thu Oct 11 02:27:46 2018 +0000
Revision:
3:f3764f852aa8
Parent:
0:8fdf9a60065b
Nucreo 446 + SSD1331 test version;

Who changed what in which revision?

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