+++ /dev/null
-/*\r
- * FreeRTOS Kernel V10.0.0\r
- * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.\r
- *\r
- * Permission is hereby granted, free of charge, to any person obtaining a copy of\r
- * this software and associated documentation files (the "Software"), to deal in\r
- * the Software without restriction, including without limitation the rights to\r
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\r
- * the Software, and to permit persons to whom the Software is furnished to do so,\r
- * subject to the following conditions:\r
- *\r
- * The above copyright notice and this permission notice shall be included in all\r
- * copies or substantial portions of the Software. If you wish to use our Amazon\r
- * FreeRTOS name, please do so in a fair use way that does not cause confusion.\r
- *\r
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\r
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\r
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\r
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
- *\r
- * http://www.FreeRTOS.org\r
- * http://aws.amazon.com/freertos\r
- *\r
- * 1 tab == 4 spaces!\r
- */\r
-\r
-/* Scheduler includes. */\r
-#include "FreeRTOS.h"\r
-#include "task.h"\r
-#include "app_util.h"\r
-\r
-#ifdef SOFTDEVICE_PRESENT\r
-#include "nrf_soc.h"\r
-#include "nrf_sdh.h"\r
-#include "app_error.h"\r
-#include "app_util_platform.h"\r
-#endif\r
-\r
-/*-----------------------------------------------------------\r
- * Implementation of functions defined in portable.h for the ARM CM4F port.\r
- * CMSIS compatible layer to menage SysTick ticking source.\r
- *----------------------------------------------------------*/\r
-\r
-#if configTICK_SOURCE == FREERTOS_USE_SYSTICK\r
-\r
-\r
-#ifndef configSYSTICK_CLOCK_HZ\r
- #define configSYSTICK_CLOCK_HZ configCPU_CLOCK_HZ\r
- /* Ensure the SysTick is clocked at the same frequency as the core. */\r
- #define portNVIC_SYSTICK_CLK_BIT ( SysTick_CTRL_CLKSOURCE_Msk )\r
-#else\r
- /* The way the SysTick is clocked is not modified in case it is not the same\r
- as the core. */\r
- #define portNVIC_SYSTICK_CLK_BIT ( 0 )\r
-#endif\r
-\r
-\r
-#if configUSE_TICKLESS_IDLE == 1\r
- #error SysTick port for RF52 does not support tickless idle. Use RTC mode instead.\r
-#endif /* configUSE_TICKLESS_IDLE */\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-void xPortSysTickHandler( void )\r
-{\r
- /* The SysTick runs at the lowest interrupt priority, so when this interrupt\r
- executes all interrupts must be unmasked. There is therefore no need to\r
- save and then restore the interrupt mask value as its value is already\r
- known. */\r
- ( void ) portSET_INTERRUPT_MASK_FROM_ISR();\r
- {\r
- /* Increment the RTOS tick. */\r
- if ( xTaskIncrementTick() != pdFALSE )\r
- {\r
- /* A context switch is required. Context switching is performed in\r
- the PendSV interrupt. Pend the PendSV interrupt. */\r
- SCB->ICSR = SCB_ICSR_PENDSVSET_Msk;\r
- __SEV();\r
- }\r
- }\r
- portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 );\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-/*\r
- * Setup the systick timer to generate the tick interrupts at the required\r
- * frequency.\r
- */\r
-void vPortSetupTimerInterrupt( void )\r
-{\r
- /* Set interrupt priority */\r
- NVIC_SetPriority(SysTick_IRQn, configKERNEL_INTERRUPT_PRIORITY);\r
- /* Configure SysTick to interrupt at the requested rate. */\r
- SysTick->LOAD = ROUNDED_DIV(configSYSTICK_CLOCK_HZ, configTICK_RATE_HZ) - 1UL;\r
- SysTick->CTRL = ( portNVIC_SYSTICK_CLK_BIT | SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk );\r
-}\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-#elif configTICK_SOURCE == FREERTOS_USE_RTC\r
-\r
-#if configUSE_16_BIT_TICKS == 1\r
-#error This port does not support 16 bit ticks.\r
-#endif\r
-\r
-#include "nrf_rtc.h"\r
-#include "nrf_drv_clock.h"\r
-\r
-/*-----------------------------------------------------------*/\r
-\r
-void xPortSysTickHandler( void )\r
-{\r
-#if configUSE_TICKLESS_IDLE == 1\r
- nrf_rtc_event_clear(portNRF_RTC_REG, NRF_RTC_EVENT_COMPARE_0);\r
-#endif\r
-\r
- BaseType_t switch_req = pdFALSE;\r
- uint32_t isrstate = portSET_INTERRUPT_MASK_FROM_ISR();\r
-\r
- uint32_t systick_counter = nrf_rtc_counter_get(portNRF_RTC_REG);\r
- nrf_rtc_event_clear(portNRF_RTC_REG, NRF_RTC_EVENT_TICK);\r
-\r
- if (configUSE_DISABLE_TICK_AUTO_CORRECTION_DEBUG == 0)\r
- {\r
- /* check FreeRTOSConfig.h file for more details on configUSE_DISABLE_TICK_AUTO_CORRECTION_DEBUG */\r
- TickType_t diff;\r
- diff = (systick_counter - xTaskGetTickCount()) & portNRF_RTC_MAXTICKS;\r
-\r
- /* At most 1 step if scheduler is suspended - the xTaskIncrementTick\r
- * would return the tick state from the moment when suspend function was called. */\r
- if ((diff > 1) && (xTaskGetSchedulerState() != taskSCHEDULER_RUNNING))\r
- {\r
- diff = 1;\r
- }\r
- while ((diff--) > 0)\r
- {\r
- switch_req |= xTaskIncrementTick();\r
- }\r
- }\r
- else\r
- {\r
- switch_req = xTaskIncrementTick();\r
- }\r
-\r
- /* Increment the RTOS tick as usual which checks if there is a need for rescheduling */\r
- if ( switch_req != pdFALSE )\r
- {\r
- /* A context switch is required. Context switching is performed in\r
- the PendSV interrupt. Pend the PendSV interrupt. */\r
- SCB->ICSR = SCB_ICSR_PENDSVSET_Msk;\r
- __SEV();\r
- }\r
-\r
- portCLEAR_INTERRUPT_MASK_FROM_ISR( isrstate );\r
-}\r
-\r
-/*\r
- * Setup the RTC time to generate the tick interrupts at the required\r
- * frequency.\r
- */\r
-void vPortSetupTimerInterrupt( void )\r
-{\r
- /* Request LF clock */\r
- nrf_drv_clock_lfclk_request(NULL);\r
-\r
- /* Configure SysTick to interrupt at the requested rate. */\r
- nrf_rtc_prescaler_set(portNRF_RTC_REG, portNRF_RTC_PRESCALER);\r
- nrf_rtc_int_enable (portNRF_RTC_REG, RTC_INTENSET_TICK_Msk);\r
- nrf_rtc_task_trigger (portNRF_RTC_REG, NRF_RTC_TASK_CLEAR);\r
- nrf_rtc_task_trigger (portNRF_RTC_REG, NRF_RTC_TASK_START);\r
- nrf_rtc_event_enable(portNRF_RTC_REG, RTC_EVTEN_OVRFLW_Msk);\r
-\r
- NVIC_SetPriority(portNRF_RTC_IRQn, configKERNEL_INTERRUPT_PRIORITY);\r
- NVIC_EnableIRQ(portNRF_RTC_IRQn);\r
-}\r
-\r
-#if configUSE_TICKLESS_IDLE == 1\r
-\r
-void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime )\r
-{\r
- /*\r
- * Implementation note:\r
- *\r
- * To help debugging the option configUSE_TICKLESS_IDLE_SIMPLE_DEBUG was presented.\r
- * This option would make sure that even if program execution was stopped inside\r
- * this function no more than expected number of ticks would be skipped.\r
- *\r
- * Normally RTC works all the time even if firmware execution was stopped\r
- * and that may lead to skipping too much of ticks.\r
- */\r
- TickType_t enterTime;\r
-\r
- /* Make sure the SysTick reload value does not overflow the counter. */\r
- if ( xExpectedIdleTime > portNRF_RTC_MAXTICKS - configEXPECTED_IDLE_TIME_BEFORE_SLEEP )\r
- {\r
- xExpectedIdleTime = portNRF_RTC_MAXTICKS - configEXPECTED_IDLE_TIME_BEFORE_SLEEP;\r
- }\r
- /* Block all the interrupts globally */\r
-#ifdef SOFTDEVICE_PRESENT\r
- do{\r
- uint8_t dummy = 0;\r
- uint32_t err_code = sd_nvic_critical_region_enter(&dummy);\r
- APP_ERROR_CHECK(err_code);\r
- }while (0);\r
-#else\r
- __disable_irq();\r
-#endif\r
-\r
- enterTime = nrf_rtc_counter_get(portNRF_RTC_REG);\r
-\r
- if ( eTaskConfirmSleepModeStatus() != eAbortSleep )\r
- {\r
- TickType_t xModifiableIdleTime;\r
- TickType_t wakeupTime = (enterTime + xExpectedIdleTime) & portNRF_RTC_MAXTICKS;\r
-\r
- /* Stop tick events */\r
- nrf_rtc_int_disable(portNRF_RTC_REG, NRF_RTC_INT_TICK_MASK);\r
-\r
- /* Configure CTC interrupt */\r
- nrf_rtc_cc_set(portNRF_RTC_REG, 0, wakeupTime);\r
- nrf_rtc_event_clear(portNRF_RTC_REG, NRF_RTC_EVENT_COMPARE_0);\r
- nrf_rtc_int_enable(portNRF_RTC_REG, NRF_RTC_INT_COMPARE0_MASK);\r
-\r
- __DSB();\r
-\r
- /* Sleep until something happens. configPRE_SLEEP_PROCESSING() can\r
- * set its parameter to 0 to indicate that its implementation contains\r
- * its own wait for interrupt or wait for event instruction, and so wfi\r
- * should not be executed again. However, the original expected idle\r
- * time variable must remain unmodified, so a copy is taken. */\r
- xModifiableIdleTime = xExpectedIdleTime;\r
- configPRE_SLEEP_PROCESSING( xModifiableIdleTime );\r
- if ( xModifiableIdleTime > 0 )\r
- {\r
-#if 0 // With FreeRTOS sd_app_evt_wait increases power consumption with FreeRTOS compared to _WFE (NRFFOSDK-11174)\r
-#ifdef SOFTDEVICE_PRESENT\r
- if (nrf_sdh_is_enabled())\r
- {\r
- uint32_t err_code = sd_app_evt_wait();\r
- APP_ERROR_CHECK(err_code);\r
- }\r
- else\r
-#endif\r
-#endif // (NRFFOSDK-11174)\r
- {\r
- /* No SD - we would just block interrupts globally.\r
- * BASEPRI cannot be used for that because it would prevent WFE from wake up.\r
- */\r
- do{\r
- __WFE();\r
- } while (0 == (NVIC->ISPR[0] | NVIC->ISPR[1]));\r
- }\r
- }\r
- configPOST_SLEEP_PROCESSING( xExpectedIdleTime );\r
-\r
- nrf_rtc_int_disable(portNRF_RTC_REG, NRF_RTC_INT_COMPARE0_MASK);\r
- nrf_rtc_event_clear(portNRF_RTC_REG, NRF_RTC_EVENT_COMPARE_0);\r
-\r
- /* Correct the system ticks */\r
- {\r
- TickType_t diff;\r
- TickType_t exitTime;\r
-\r
- nrf_rtc_event_clear(portNRF_RTC_REG, NRF_RTC_EVENT_TICK);\r
- nrf_rtc_int_enable (portNRF_RTC_REG, NRF_RTC_INT_TICK_MASK);\r
-\r
- exitTime = nrf_rtc_counter_get(portNRF_RTC_REG);\r
- diff = (exitTime - enterTime) & portNRF_RTC_MAXTICKS;\r
-\r
- /* It is important that we clear pending here so that our corrections are latest and in sync with tick_interrupt handler */\r
- NVIC_ClearPendingIRQ(portNRF_RTC_IRQn);\r
-\r
- if ((configUSE_TICKLESS_IDLE_SIMPLE_DEBUG) && (diff > xExpectedIdleTime))\r
- {\r
- diff = xExpectedIdleTime;\r
- }\r
-\r
- if (diff > 0)\r
- {\r
- vTaskStepTick(diff);\r
- }\r
- }\r
- }\r
-#ifdef SOFTDEVICE_PRESENT\r
- uint32_t err_code = sd_nvic_critical_region_exit(0);\r
- APP_ERROR_CHECK(err_code);\r
-#else\r
- __enable_irq();\r
-#endif\r
-}\r
-\r
-#endif // configUSE_TICKLESS_IDLE\r
-\r
-#else // configTICK_SOURCE\r
- #error Unsupported configTICK_SOURCE value\r
-#endif // configTICK_SOURCE == FREERTOS_USE_SYSTICK\r