From 5e790cb3d7a17a5e5376f02424ceea195f24c528 Mon Sep 17 00:00:00 2001 From: schneider <schneider@blinkenlichts.net> Date: Sun, 14 Jul 2019 14:38:05 +0200 Subject: [PATCH] feat(epicardium): First BLE support --- card10-cross.ini | 4 +- epicardium/main.c | 2 +- epicardium/meson.build | 1 + epicardium/modules/ble.c | 180 +++++++++--------- .../BTLE/stack/platform/max32665/wsf_os.c | 4 +- lib/sdk/Libraries/BTLE/wsf/include/wsf_os.h | 1 + .../Libraries/BTLE/wsf/include/wsf_timer.h | 2 + .../wsf/sources/port/baremetal/wsf_timer.c | 24 +++ 8 files changed, 122 insertions(+), 96 deletions(-) diff --git a/card10-cross.ini b/card10-cross.ini index ca8d0540..04f10337 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 9d7a578a..5b08d927 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 bf727f07..a3b06df6 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 ae56ddc6..7e0ab68c 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 d4e0c647..62012a7d 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 674ffb73..a9ffd502 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 41259e38..0ba11f66 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 3ed48a43..4b013431 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; } -- GitLab