Milosch Meriac / CThunk

Dependents:   cthunk_example

Revision:
3:51023d181133
Parent:
2:3197c4a8ba85
Child:
4:e4a106e8f3fe
--- a/CThunk.h	Fri Aug 15 16:03:48 2014 +0000
+++ b/CThunk.h	Wed Aug 20 07:49:00 2014 +0000
@@ -25,6 +25,7 @@
 
 /* IRQ/Exception compatible thunk entry function */
 typedef void (*CThunkEntry)(void);
+typedef void (*CThunkCallback)(void* instance, void* context);
 
 template<class T>
 class CThunk
@@ -35,11 +36,6 @@
 
         inline CThunk(T *instance)
         {
-            init(*instance, NULL, NULL);
-        }
-
-        inline CThunk(T &instance)
-        {
             init(instance, NULL, NULL);
         }
 
@@ -58,40 +54,31 @@
             init(instance, callback, context);
         }
 
-        inline CThunk& operator=(T &instance)
+        inline void callback(CCallback callback)
         {
-            m_thunk.instance = &instance;
-            return *this;
-        }
-
-        inline CThunk& operator=(CCallback callback)
-        {
-            m_thunk.callback = callback;
-            return *this;
+            m_callback = callback;
         }
 
-        inline CThunk& operator=(CCallbackSimple callback)
+        inline void callback(CCallbackSimple callback)
         {
-            m_thunk.callback = (CCallback)callback;
-            return *this;
+            m_callback = (CCallback)callback;
         }
 
-        inline CThunk& operator=(void* context)
+        inline void context(void* context)
+        {
+            m_thunk.context = (uint32_t)context;
+        }
+
+        inline void context(uint32_t context)
         {
             m_thunk.context = context;
-            return *this;
-        }
-
-        inline CThunk& operator=(uint32_t context)
-        {
-            m_thunk.context = (void*)context;
-            return *this;
         }
 
         /* get thunk entry point for connecting rhunk to an IRQ table */
         inline operator CThunkEntry(void)
         {
-            return (CThunkEntry)&m_thunk;
+            /* TODO: check thumb */
+            return (CThunkEntry)(((uint32_t)&m_thunk)|1);
         }
 
         /* get thunk entry point for connecting rhunk to an IRQ table */
@@ -103,30 +90,45 @@
         /* simple test function */
         inline void call(void)
         {
-            ((CThunkEntry)&m_thunk)();
+            /* TODO: check thumb */
+            ((CThunkEntry)(((uint32_t)&m_thunk)|1))();
         }
 
     private:
+        volatile CCallback m_callback;
         typedef struct
         {
-            uint32_t code;
-            T* instance;
-            void* context;
-            CCallback callback;
+            volatile uint32_t code;
+            volatile uint32_t instance;
+            volatile uint32_t context;
+            volatile uint32_t callback;
         } __attribute__((packed)) CThunkTrampoline;
 
-        CThunkTrampoline m_thunk;
+        inline void callback(void* context)
+        {
+            pc.printf("Trampoline: context=0x%08X\n", context);
+        }
 
-        inline void init(T &instance, CCallback callback, void* context)
+        static void trampoline(void* instance, void* context)
+        {
+            ((CThunk<T>*)instance)->callback(context);
+        }
+
+        volatile CThunkTrampoline m_thunk;
+
+        inline void init(T *instance, CCallback callback, void* context)
         {
 #ifdef __CORTEX_M3
             m_thunk.code = 0x8003E89F;
 #else
 #error "TODO: add support for non-cortex-m3 trampoline, too"
 #endif
-            m_thunk.instance = &instance;
-            m_thunk.context = context;
-            m_thunk.callback = callback;
+            m_thunk.context = (uint32_t)context;
+            m_thunk.instance = (uint32_t)instance;
+            m_thunk.callback = (uint32_t)&trampoline;
+            m_callback = callback;
+            __ISB();
+            __DSB();
         }
 };