diff --git a/card10-cross.ini b/card10-cross.ini
index ca8d05402ad57e3585656580a40b26748ede7e8d..04f103378b276ac7e8b8a47567781c2e75a72190 100644
--- a/card10-cross.ini
+++ b/card10-cross.ini
@@ -4,9 +4,9 @@ ar = 'arm-none-eabi-ar'
 strip = 'arm-none-eabi-strip'
 
 [properties]
-c_args      = ['-mthumb', '-mcpu=cortex-m4', '-mfloat-abi=hard', '-mfpu=fpv4-sp-d16', '-Wa,-mimplicit-it=thumb', '-ffunction-sections', '-fdata-sections', '-fsingle-precision-constant', '-fno-isolate-erroneous-paths-dereference']
+c_args      = ['-mthumb', '-mcpu=cortex-m4', '-mfloat-abi=softfp', '-mfpu=fpv4-sp-d16', '-Wa,-mimplicit-it=thumb', '-ffunction-sections', '-fdata-sections', '-fsingle-precision-constant', '-fno-isolate-erroneous-paths-dereference', '-DWSF_TRACE_ENABLED=TRUE', '-DWSF_ASSERT_ENABLED=TRUE', '-DWSF_MS_PER_TICK=1', '-DINIT_BROADCASTER', '-DINIT_PERIPHERAL', '-DINIT_ENCRYPTED']
 
-c_link_args = ['-mthumb', '-mcpu=cortex-m4', '-mfloat-abi=hard', '-mfpu=fpv4-sp-d16', '-Wl,--start-group', '-lc', '-lnosys', '-Wl,--end-group', '--specs=nano.specs']
+c_link_args = ['-mthumb', '-mcpu=cortex-m4', '-mfloat-abi=softfp', '-mfpu=fpv4-sp-d16', '-Wl,--start-group', '-lc', '-lnosys', '-Wl,--end-group', '--specs=nano.specs', '../lib/sdk/Libraries/BTLE/cordio-phy.a']
 
 target_defs = ['-DTARGET=32665', '-DTARGET_REV=0x4131', '-DBOARD_CARD10=1']
 
diff --git a/epicardium/main.c b/epicardium/main.c
index 9d7a578a83642802056a129bf7655419c090ed4f..5b08d9270f8dfe7ebb3a77a368f079a16f0ab774 100644
--- a/epicardium/main.c
+++ b/epicardium/main.c
@@ -109,7 +109,7 @@ int main(void)
 	if (xTaskCreate(
 		vBleTask,
 		(const char*)"BLE",
-		configMINIMAL_STACK_SIZE,
+		configMINIMAL_STACK_SIZE * 10,
 		NULL,
 		tskIDLE_PRIORITY  + 1,
         NULL
diff --git a/epicardium/meson.build b/epicardium/meson.build
index bf727f0715673fdf9e430ddd8685a777ac1c3b10..a3b06df61483023593f109c11c51d6abccdceb23 100644
--- a/epicardium/meson.build
+++ b/epicardium/meson.build
@@ -73,6 +73,7 @@ elf = executable(
   'cdcacm.c',
   'main.c',
   'support.c',
+  'stack_fit.c',
   module_sources,
   l0der_sources,
   dependencies: [libcard10, max32665_startup_core0, maxusb, libff13, ble],
diff --git a/epicardium/modules/ble.c b/epicardium/modules/ble.c
index ae56ddc698798027a5b70a7e24c019d382f2e445..7e0ab68ca6607779358ae2cce6050aa8f95824fb 100644
--- a/epicardium/modules/ble.c
+++ b/epicardium/modules/ble.c
@@ -4,28 +4,28 @@
 #include "wsf_timer.h"
 #include "wsf_trace.h"
 #include "app_ui.h"
-#include "ll_api.h"
-#include "sch_api.h"
 #include "fit/fit_api.h"
-#include "mxc_config.h"
-#include "gcr_regs.h"
-#include "mcr_regs.h"
-#include "hci_core.h"
+#include "hci_vs.h"
 
 #include "FreeRTOS.h"
 #include "timers.h"
 
 #include <stdio.h>
 #include <string.h>
+#include <stdbool.h>
+
+
+/* Size of buffer for stdio functions */
+#define WSF_BUF_POOLS       6
+#define WSF_BUF_SIZE        0x1048
+
+uint32_t SystemHeapSize=WSF_BUF_SIZE;
+uint32_t SystemHeap[WSF_BUF_SIZE/4];
+uint32_t SystemHeapStart;
 
 /* Task ID for the ble handler */
 static TaskHandle_t ble_task_id = NULL;
 
-/* Number of WSF buffer pools */
-#define WSF_BUF_POOLS              6
-
-/*! Free memory for pool buffers (use word elements for word alignment). */
-static uint32_t mainBufMem[3584/sizeof(uint32_t)+96];
 
 /*! Default pool descriptor. */
 static wsfBufPoolDesc_t mainPoolDesc[WSF_BUF_POOLS] =
@@ -35,40 +35,31 @@ static wsfBufPoolDesc_t mainPoolDesc[WSF_BUF_POOLS] =
   {  64,  4 },
   { 128,  4 },
   { 256,  4 },
-  { 384,  4 }
+  { 512,  4 }
 };
 
+/*! \brief  Stack initialization for app. */
+extern void StackInitFit(void);
 
-static void PlatformInit(void)
+/*************************************************************************************************/
+void PalSysAssertTrap(void)
 {
-    /* Change the pullup on the RST pin to 25K */
-    /* TODO: Is this really needed? */
-    MXC_MCR->ctrl = 0x202;
-
-    /* Set VREGO_D to 1.3V */
-    *((volatile uint32_t*)0x40004410) = 0x50;
-
-    /* Set TX LDO to 1.1V and enable LDO. Set RX LDO to 0.9V and enable LDO */
-    MXC_GCR->btleldocn = 0xD9; // TX 1.1V RX 0.9V
-
-    /* Power up the 32MHz XO */
-    MXC_GCR->clkcn |= MXC_F_GCR_CLKCN_X32M_EN;
-
-    /* Enable peripheral clocks */
-    /* TODO: Is this really needed? */
-    MXC_GCR->perckcn0 &= ~(MXC_F_GCR_PERCKCN0_GPIO0D | MXC_F_GCR_PERCKCN0_GPIO1D);  // Clear GPIO0 and GPIO1 Disable
-    MXC_GCR->perckcn1 &= ~(MXC_F_GCR_PERCKCN1_BTLED | MXC_F_GCR_PERCKCN1_TRNGD );  // Clear BTLE and ICACHE0 disable
+    while(1) {}
 }
 
-static void myTrace(const char *pStr, va_list args)
+
+/*************************************************************************************************/
+static bool_t myTrace(const uint8_t *pBuf, uint32_t len)
 {
     extern uint8_t wsfCsNesting;
 
     if (wsfCsNesting == 0)
     {
-        vprintf(pStr, args);
-        printf("\r\n");
+        fwrite(pBuf, len, 1, stdout);
+        return TRUE;
     }
+
+    return FALSE;
 }
 
 /*************************************************************************************************/
@@ -80,11 +71,20 @@ static void myTrace(const char *pStr, va_list args)
 /*************************************************************************************************/
 static void WsfInit(void)
 {
+    uint32_t bytesUsed;
     WsfTimerInit();
-    WsfBufInit(sizeof(mainBufMem), (uint8_t*)mainBufMem, WSF_BUF_POOLS, mainPoolDesc);
-    WsfTraceRegister(myTrace);
+
+    SystemHeapStart = (uint32_t)&SystemHeap;
+    memset(SystemHeap, 0, sizeof(SystemHeap));
+    //printf("SystemHeapStart = 0x%x\n", SystemHeapStart);
+    //printf("SystemHeapSize = 0x%x\n", SystemHeapSize);
+    bytesUsed = WsfBufInit(WSF_BUF_POOLS, mainPoolDesc);
+    printf("bytesUsed = %u\n", (unsigned int)bytesUsed);
+    
+    WsfTraceRegisterHandler(myTrace);
+    WsfTraceEnable(TRUE);
 }
-/* TODO: WTF? */
+/* TODO: We need a source of MACs */
 /*
  * In two-chip solutions, setting the address must wait until the HCI interface is initialized.
  * This handler can also catch other Application events, but none are currently implemented.
@@ -98,68 +98,64 @@ void SetAddress(uint8_t event)
     switch (event) {
     case APP_UI_RESET_CMPL:
         printf("Setting address -- MAC %02X:%02X:%02X:%02X:%02X:%02X\n", bdAddr[5], bdAddr[4], bdAddr[3], bdAddr[2], bdAddr[1], bdAddr[0]);
-        LlSetBdAddr((uint8_t*)&bdAddr);
-        LlGetBdAddr(hciCoreCb.bdAddr);
+        HciVsSetBdAddr(bdAddr);
         break;
     default:
         break;
     }
 }
 
-/*************************************************************************************************/
-/*!
- *  \brief  Initialize MAC layer.
- *
- *  \param  None.
- *
- *  \return None.
- */
-/*************************************************************************************************/
-extern int8_t tx_rfpower_on;
-void MacInit(void)
+static StaticTimer_t x;
+TimerHandle_t timerWakeup = NULL;
+int lasttick = 0;
+bool schedule_needed = false;
+
+static void vTimerCallback(xTimerHandle pxTimer)
 {
-    wsfHandlerId_t handlerId;
-
-    /* Initialize link layer. */
-    BbInit();
-    handlerId = WsfOsSetNextHandler(SchHandler);
-    SchInit(handlerId);
-    LlAdvSlaveInit();
-    LlConnSlaveInit();
-    handlerId = WsfOsSetNextHandler(LlHandler);
-    LlHandlerInit(handlerId);
+    //printf("wake\n");
+    int tick = xTaskGetTickCount();
+    printf("WsfTimerUpdate(%d)\n", tick - lasttick);
+    WsfTimerUpdate(tick - lasttick);
+    lasttick = tick;
+    //printf("done\n");
 }
 
+static void notify(void)
+{
+	BaseType_t xHigherPriorityTaskWoken = pdFALSE;
+    if(xPortIsInsideInterrupt()) {
+	    vTaskNotifyGiveFromISR(ble_task_id, &xHigherPriorityTaskWoken);
+        portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
+    } else {
+	     xTaskNotifyGive(ble_task_id);
+    }
+}
 
+void WsfTimerNotify(void)
+{
+    //printf("WsfTimerNotify\n");
+    notify();
+}
 
+void wsf_ble_signal_event(void)
+{
+    //printf("wsf_ble_signal_event\n");
+    notify();
+}
 
-static StaticTimer_t x;
-TimerHandle_t timerWakeup;
-int lasttick = 0;
-
-static void vTimerCallback(xTimerHandle pxTimer)
+static void scheduleTimer(void)
 {
     bool_t          timerRunning;
     wsfTimerTicks_t time_to_next_expire;
-    do {
-        int tick = xTaskGetTickCount();
-        WsfTimerUpdate(tick - lasttick);
-        lasttick = tick;
-        time_to_next_expire = WsfTimerNextExpiration(&timerRunning);
-    } while (timerRunning && time_to_next_expire == 0);
 
+    time_to_next_expire = WsfTimerNextExpiration(&timerRunning);
 
     if(timerRunning) {
-        printf("time_to_next_expire = %d\n", time_to_next_expire);
-        timerWakeup = xTimerCreateStatic(
-            "timerWakeup", /* name */
-            pdMS_TO_TICKS(time_to_next_expire), /* period/time */
-            pdFALSE, /* auto reload */
-            NULL, /* timer ID */
-            vTimerCallback, &x); /* callback */
-
+        //printf("time_to_next_expire = %d\n", time_to_next_expire);
+        //printf("change period\n");
         if(timerWakeup != NULL) {
-            xTimerStart(timerWakeup, 0);
+            xTimerChangePeriod(timerWakeup, pdMS_TO_TICKS(time_to_next_expire), 0);
+            //printf("insert done\n");
         } else {
             printf("could not create timer\n");
         }
@@ -168,34 +164,36 @@ static void vTimerCallback(xTimerHandle pxTimer)
     }
 }
 
-
 static void ble_init(void)
 {
-    PlatformInit();
     WsfInit();
-    MacInit();
-    //StackInitFit();
-    //FitStart();
+    StackInitFit();
+    NVIC_SetPriority(BTLE_SFD_TO_IRQn, 2);
+    NVIC_SetPriority(BTLE_TX_DONE_IRQn, 2);
+    NVIC_SetPriority(BTLE_RX_RCVD_IRQn, 2);
+    FitStart();
 
     /* Register a handler for Application events */
     AppUiActionRegister(SetAddress);
 
     lasttick = xTaskGetTickCount();
-    vTimerCallback(NULL);
-}
 
+    timerWakeup = xTimerCreateStatic(
+        "timerWakeup", /* name */
+        pdMS_TO_TICKS(1), /* period/time */
+        pdFALSE, /* auto reload */
+        NULL, /* timer ID */
+        vTimerCallback, &x); /* callback */
+}
 
 void vBleTask(void*pvParameters)
 {
 	ble_task_id = xTaskGetCurrentTaskHandle();
-
     ble_init();
-    const TickType_t xDelay = 500 / portTICK_PERIOD_MS;
 
     while (1){
-        // TODO: this need some timing and sleeping
+		ulTaskNotifyTake(pdTRUE, portTICK_PERIOD_MS * 1000);
         wsfOsDispatcher();
-        vTimerCallback(NULL);
-        vTaskDelay( xDelay );
+        scheduleTimer();
     }
 }
diff --git a/lib/sdk/Libraries/BTLE/stack/platform/max32665/wsf_os.c b/lib/sdk/Libraries/BTLE/stack/platform/max32665/wsf_os.c
index d4e0c647b0d4be27ee15b89e2b368ff8a72916bf..62012a7d4bb84a58ac72aff1bd1eff0c3047ff8b 100644
--- a/lib/sdk/Libraries/BTLE/stack/platform/max32665/wsf_os.c
+++ b/lib/sdk/Libraries/BTLE/stack/platform/max32665/wsf_os.c
@@ -132,7 +132,7 @@ void WsfSetEvent(wsfHandlerId_t handlerId, wsfEventMask_t event)
   WSF_CS_EXIT(cs);
 
   /* set event in OS */
-  // wsf_mbed_ble_signal_event();
+  wsf_ble_signal_event();
 }
 
 /*************************************************************************************************/
@@ -157,7 +157,7 @@ void WsfTaskSetReady(wsfHandlerId_t handlerId, wsfTaskEvent_t event)
   WSF_CS_EXIT(cs);
 
   /* set event in OS */
-  // wsf_mbed_ble_signal_event();
+  wsf_ble_signal_event();
 }
 
 /*************************************************************************************************/
diff --git a/lib/sdk/Libraries/BTLE/wsf/include/wsf_os.h b/lib/sdk/Libraries/BTLE/wsf/include/wsf_os.h
index 674ffb73d1f572074448d48066ab141b0c337304..a9ffd502c8009414b4501723a6667bb79c24f950 100644
--- a/lib/sdk/Libraries/BTLE/wsf/include/wsf_os.h
+++ b/lib/sdk/Libraries/BTLE/wsf/include/wsf_os.h
@@ -216,6 +216,7 @@ void wsfOsDispatcher(void);
 /*************************************************************************************************/
 void WsfOsInit(void);
 
+void wsf_ble_signal_event(void);
 /*! \} */    /* WSF_OS_API */
 
 #ifdef __cplusplus
diff --git a/lib/sdk/Libraries/BTLE/wsf/include/wsf_timer.h b/lib/sdk/Libraries/BTLE/wsf/include/wsf_timer.h
index 41259e38c80ec073d008931f4d7f6896ef64bbf1..0ba11f66625fc3c719cf18209f637166f607add9 100644
--- a/lib/sdk/Libraries/BTLE/wsf/include/wsf_timer.h
+++ b/lib/sdk/Libraries/BTLE/wsf/include/wsf_timer.h
@@ -164,6 +164,8 @@ void WsfTimerSleep(void);
 /*************************************************************************************************/
 void WsfTimerSleepUpdate(void);
 
+void WsfTimerNotify(void);
+
 /*! \} */    /* WSF_TIMER_API */
 
 #ifdef __cplusplus
diff --git a/lib/sdk/Libraries/BTLE/wsf/sources/port/baremetal/wsf_timer.c b/lib/sdk/Libraries/BTLE/wsf/sources/port/baremetal/wsf_timer.c
index 3ed48a4360efaee01858a83c15e31c64b8afd888..4b0134315c96f2e025f85413830ff80240654c1b 100644
--- a/lib/sdk/Libraries/BTLE/wsf/sources/port/baremetal/wsf_timer.c
+++ b/lib/sdk/Libraries/BTLE/wsf/sources/port/baremetal/wsf_timer.c
@@ -111,7 +111,9 @@ static void wsfTimerRemove(wsfTimer_t *pTimer)
 {
   wsfTimer_t  *pElem;
   wsfTimer_t  *pPrev = NULL;
+  bool_t      newHead = FALSE;
 
+  /* TODO: why is there no lock here? */
   pElem = (wsfTimer_t *) wsfTimerTimerQueue.pHead;
 
   /* find timer in queue */
@@ -128,10 +130,21 @@ static void wsfTimerRemove(wsfTimer_t *pTimer)
   /* if timer found remove from queue */
   if (pElem != NULL)
   {
+    if (pElem == wsfTimerTimerQueue.pHead)
+    {
+      newHead = TRUE;
+    }
     WsfQueueRemove(&wsfTimerTimerQueue, pTimer, pPrev);
 
     pTimer->isStarted = FALSE;
   }
+
+  if (newHead)
+  {
+    /* We have a new head. Notify the OS. */
+    /* TODO: Not sure if this should be inside a lock */
+    WsfTimerNotify();
+  }
 }
 
 /*************************************************************************************************/
@@ -179,6 +192,13 @@ static void wsfTimerInsert(wsfTimer_t *pTimer, wsfTimerTicks_t ticks)
 
   /* task schedule unlock */
   WsfTaskUnlock();
+
+  if(wsfTimerTimerQueue.pHead == pTimer)
+  {
+    /* The timer is new head. Notify the OS. */
+    /* TODO: Not sure if this should be inside the lock */
+    WsfTimerNotify();
+  }
 }
 
 /*************************************************************************************************/
@@ -380,6 +400,10 @@ wsfTimer_t *WsfTimerServiceExpired(wsfTaskId_t taskId)
 
     WSF_TRACE_INFO1("Timer expired pTimer:0x%x", pElem);
 
+    /* We have a new head. Notify the OS. */
+    /* TODO: Not sure if this should be inside the lock */
+    WsfTimerNotify();
+
     /* return timer */
     return pElem;
   }