From db0a9b1f06e85e62f96b6d57f6c29377fb8d8799 Mon Sep 17 00:00:00 2001 From: Sissors Date: Mon, 25 Aug 2014 20:10:54 +0200 Subject: [PATCH] Update HAL-KSPDK files to 1.0 part 1 Everything except drivers and hal folder --- .../{utilities => osa}/fsl_os_abstraction.h | 8 - .../osa/fsl_os_abstraction_bm.h | 185 ++++ .../fsl_os_abstraction_mbed.h | 0 .../osa/src/fsl_os_abstraction_bm.c | 983 ++++++++++++++++++ .../src/fsl_os_abstraction_mbed.c | 0 .../utilities/src/fsl_misc_utilities.c | 68 ++ .../TARGET_KPSDK_CODE/utilities/sw_timer.h | 191 ---- 7 files changed, 1236 insertions(+), 199 deletions(-) rename libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/{utilities => osa}/fsl_os_abstraction.h (99%) create mode 100644 libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/osa/fsl_os_abstraction_bm.h rename libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/{utilities => osa}/fsl_os_abstraction_mbed.h (100%) create mode 100644 libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/osa/src/fsl_os_abstraction_bm.c rename libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/{utilities => osa}/src/fsl_os_abstraction_mbed.c (100%) create mode 100644 libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/utilities/src/fsl_misc_utilities.c delete mode 100644 libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/utilities/sw_timer.h diff --git a/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/utilities/fsl_os_abstraction.h b/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/osa/fsl_os_abstraction.h similarity index 99% rename from libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/utilities/fsl_os_abstraction.h rename to libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/osa/fsl_os_abstraction.h index 18cd8c3cf6..08191bfe25 100644 --- a/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/utilities/fsl_os_abstraction.h +++ b/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/osa/fsl_os_abstraction.h @@ -84,14 +84,6 @@ typedef enum _osa_critical_section_mode_t #define USE_RTOS 1 #include "fsl_os_abstraction_ucosiii.h" -#elif defined (FSL_RTOS_CMSIS) - #define USE_RTOS 1 - #include "fsl_os_abstraction_cmsis.h" - -#elif defined (FSL_RTOS_MBED) - #define USE_RTOS 1 - #include "fsl_os_abstraction_mbed.h" - #else #define USE_RTOS 0 #include "fsl_os_abstraction_bm.h" diff --git a/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/osa/fsl_os_abstraction_bm.h b/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/osa/fsl_os_abstraction_bm.h new file mode 100644 index 0000000000..14efd21a6b --- /dev/null +++ b/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/osa/fsl_os_abstraction_bm.h @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#if !defined(__FSL_OS_ABSTRACTION_BM_H__) +#define __FSL_OS_ABSTRACTION_BM_H__ + + +/*! + * @addtogroup os_abstraction_bm + * @{ + */ + +/******************************************************************************* + * Declarations + ******************************************************************************/ + +/*! @brief Type for an semaphore */ +typedef struct Semaphore +{ + volatile bool isWaiting; /*!< Is any task waiting for a timeout on this object */ + volatile uint8_t semCount; /*!< The count value of the object */ + uint32_t time_start; /*!< The time to start timeout */ + uint32_t timeout; /*!< Timeout to wait in milliseconds */ +} semaphore_t; + +/*! @brief Type for a mutex */ +typedef struct Mutex +{ + volatile bool isWaiting; /*!< Is any task waiting for a timeout on this mutex */ + volatile bool isLocked; /*!< Is the object locked or not */ + uint32_t time_start; /*!< The time to start timeout */ + uint32_t timeout; /*!< Timeout to wait in milliseconds */ +} mutex_t; + +/*! @brief Type for an event flags group, bit 32 is reserved */ +typedef uint32_t event_flags_t; + +/*! @brief Type for an event object */ +typedef struct Event +{ + volatile bool isWaiting; /*!< Is any task waiting for a timeout on this event */ + uint32_t time_start; /*!< The time to start timeout */ + uint32_t timeout; /*!< Timeout to wait in milliseconds */ + volatile event_flags_t flags; /*!< The flags status */ + osa_event_clear_mode_t clearMode; /*!< Auto clear or manual clear */ +} event_t; + +/*! @brief Type for task parameter */ +typedef void* task_param_t; + +/*! @brief Type for a task pointer */ +typedef void (* task_t)(task_param_t param); + +/*! @brief Task control block for bare metal. */ +typedef struct TaskControlBlock +{ + task_t p_func; /*!< Task's entry */ + task_param_t param; /*!< Task's parameter */ + struct TaskControlBlock *next; /*!< Pointer to next task control block */ + struct TaskControlBlock *prev; /*!< Pointer to previous task control block */ +} task_control_block_t; + +/*! @brief Type for a task handler, returned by the OSA_TaskCreate function */ +typedef task_control_block_t* task_handler_t; + +/*! @brief Type for a task stack */ +typedef uint32_t task_stack_t; + +/*! @brief Type for a message queue */ +typedef struct MsgQueue +{ + uint32_t *queueMem; /*!< Points to the queue memory */ + uint16_t number; /*!< The number of messages in the queue */ + uint16_t size; /*!< The size in words of each message */ + uint16_t head; /*!< Index of the next message to be read */ + uint16_t tail; /*!< Index of the next place to write to */ + semaphore_t queueSem; /*!< Semaphore wakeup tasks waiting for msg */ + volatile bool isEmpty; /*!< Whether queue is empty */ +}msg_queue_t; + +/*! @brief Type for a message queue handler */ +typedef msg_queue_t* msg_queue_handler_t; + +/*! @brief Constant to pass as timeout value in order to wait indefinitely. */ +#define OSA_WAIT_FOREVER 0xFFFFFFFFU + +/*! @brief How many tasks can the bare metal support. */ +#define TASK_MAX_NUM 5 + +/*! + * @name Thread management + * @{ + */ + +/*! + * @brief Defines a task. + * + * This macro defines resources for a task statically. Then, the OSA_TaskCreate + * creates the task based-on these resources. + * + * @param task The task function. + * @param stackSize The stack size this task needs in bytes. + */ +#define OSA_TASK_DEFINE(task, stackSize) \ + task_stack_t* task##_stack = NULL; \ + task_handler_t task##_task_handler + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus*/ + +/*! + * @brief Calls all task functions one time except for the current task. + * + * This function calls all other task functions one time. If current + * task is waiting for an event triggered by other tasks, this function + * could be used to trigger the event. + * + * @note There should be only one task calls this function, if more than + * one task call this function, stack overflow may occurs. Be careful + * to use this function. + * + */ +void OSA_PollAllOtherTasks(void); + +#if defined(__cplusplus) +} +#endif /* __cplusplus*/ + +/* @} */ + +/*! + * @name Message queues + * @{ + */ + +/*! + * @brief This macro statically reserves the memory required for the queue. + * + * @param name Identifier for the memory region. + * @param number Number of elements in the queue. + * @param size Size of every element in words. + */ +#define MSG_QUEUE_DECLARE(name, number, size) uint32_t queueMem_##name[number * size]; \ + msg_queue_t entity_##name = { \ + .queueMem = queueMem_##name \ + }; \ + msg_queue_t *name = &(entity_##name) + +/* @} */ + + +/*! @}*/ + +#endif /* __FSL_OS_ABSTRACTION_BM_H__ */ +/******************************************************************************* + * EOF + ******************************************************************************/ + diff --git a/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/utilities/fsl_os_abstraction_mbed.h b/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/osa/fsl_os_abstraction_mbed.h similarity index 100% rename from libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/utilities/fsl_os_abstraction_mbed.h rename to libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/osa/fsl_os_abstraction_mbed.h diff --git a/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/osa/src/fsl_os_abstraction_bm.c b/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/osa/src/fsl_os_abstraction_bm.c new file mode 100644 index 0000000000..40fcab69b3 --- /dev/null +++ b/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/osa/src/fsl_os_abstraction_bm.c @@ -0,0 +1,983 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include "fsl_os_abstraction.h" +#include "fsl_interrupt_manager.h" +#include "fsl_clock_manager.h" +#include "fsl_lptmr_hal.h" +#include "fsl_lptmr_features.h" +/* Include lptmr features to check wether lptimer module is available. */ + +/* Only one lptmr and always use it. */ +#define BM_LPTMR_INSTANCE 0 +#define BM_LPTMR_BASE LPTMR0_BASE + +/*FUNCTION********************************************************************** + * + * Function Name : time_diff + * Description : This function gets the difference between two time stamp, + * time overflow is considered. + * + *END**************************************************************************/ +static uint32_t time_diff(uint32_t time_start, uint32_t time_end) +{ + if (time_end >= time_start) + { + return time_end - time_start; + } + else + { + /* lptmr count is 16 bits. */ + return 0xFFFFU - time_start + time_end + 1; + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : OSA_SemaCreate + * Description : This function is used to create a semaphore. Return + * kStatus_OSA_Success if create successfully, otherwise return kStatus_OSA_Error. + * + *END**************************************************************************/ +osa_status_t OSA_SemaCreate(semaphore_t *pSem, uint8_t initValue) +{ + assert(pSem); + + pSem->semCount = initValue; + pSem->isWaiting = false; + pSem->time_start = 0u; + pSem->timeout = 0u; + + return kStatus_OSA_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : OSA_SemaWait + * Description : This function checks the semaphore's counting value, if it is + * positive, decreases it and returns kStatus_OSA_Success, otherwise, timeout + * will be used for wait. The parameter timeout indicates how long should wait + * in milliseconds. Pass OSA_WAIT_FOREVER to wait indefinitely, pass 0 will + * return kStatus_OSA_Timeout immediately if semaphore is not positive. + * This function returns kStatus_OSA_Success if the semaphore is received, returns + * kStatus_OSA_Timeout if the semaphore is not received within the specified + * 'timeout', returns kStatus_OSA_Error if any errors occur during waiting, + * returns kStatus_OSA_Idle if the semaphore is not available and 'timeout' is + * not exhausted, because wait functions should not block with bare metal. + * + *END**************************************************************************/ +osa_status_t OSA_SemaWait(semaphore_t *pSem, uint32_t timeout) +{ + uint32_t currentTime; + + assert(pSem); + + /* Check the sem count first. Deal with timeout only if not already set */ + if (pSem->semCount) + { + INT_SYS_DisableIRQGlobal(); + pSem->semCount --; + pSem->isWaiting = false; + INT_SYS_EnableIRQGlobal(); + return kStatus_OSA_Success; + } + else + { + if (0 == timeout) + { + /* If timeout is 0 and semaphore is not available, return kStatus_OSA_Timeout. */ + return kStatus_OSA_Timeout; + } + else if (pSem->isWaiting) + { + /* Check for timeout */ + currentTime = OSA_TimeGetMsec(); + if (pSem->timeout < time_diff(pSem->time_start, currentTime)) + { + INT_SYS_DisableIRQGlobal(); + pSem->isWaiting = false; + INT_SYS_EnableIRQGlobal(); + return kStatus_OSA_Timeout; + } + } + else if (timeout != OSA_WAIT_FOREVER) /* If don't wait forever, start the timer */ + { + /* Start the timeout counter */ + INT_SYS_DisableIRQGlobal(); + pSem->isWaiting = true; + INT_SYS_EnableIRQGlobal(); + pSem->time_start = OSA_TimeGetMsec(); + pSem->timeout = timeout; + } + } + + return kStatus_OSA_Idle; +} + +/*FUNCTION********************************************************************** + * + * Function Name : OSA_SemaPost + * Description : This function is used to wake up one task that wating on the + * semaphore. If no task is waiting, increase the semaphore. The function returns + * kStatus_OSA_Success if the semaphre is post successfully, otherwise returns + * kStatus_OSA_Error. + * + *END**************************************************************************/ +osa_status_t OSA_SemaPost(semaphore_t *pSem) +{ + assert(pSem); + /* The max value is 0xFF */ + if (0xFF == pSem->semCount) + { + return kStatus_OSA_Error; + } + INT_SYS_DisableIRQGlobal(); + ++pSem->semCount; + INT_SYS_EnableIRQGlobal(); + + return kStatus_OSA_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : OSA_SemaDestroy + * Description : This function is used to destroy a semaphore. + * Return kStatus_OSA_Success if the semaphore is destroyed successfully, otherwise + * return kStatus_OSA_Error. + * + *END**************************************************************************/ +osa_status_t OSA_SemaDestroy(semaphore_t *pSem) +{ + assert(pSem); + + return kStatus_OSA_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : OSA_MutexCreate + * Description : This function is used to create a mutex. + * Return kStatus_OSA_Success if create successfully, otherwise return kStatus_OSA_Error. + * + *END**************************************************************************/ +osa_status_t OSA_MutexCreate(mutex_t *pMutex) +{ + assert(pMutex); + + pMutex->isLocked = false; + pMutex->isWaiting = false; + pMutex->time_start = 0u; + pMutex->timeout = 0u; + + return kStatus_OSA_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : OSA_MutexLock + * Description : This function checks the mutex's status, if it is unlocked, + * lock it and returns kStatus_OSA_Success, otherwise, timeout will be used for + * wait. The parameter timeout indicates how long should wait in milliseconds. + * Pass OSA_WAIT_FOREVER to wait indefinitely, pass 0 will return the value + * kStatus_OSA_Timeout immediately if mutex is locked. + * This function returns kStatus_OSA_Success if the mutex is obtained, returns + * kStatus_OSA_Timeout if the mutex is not obtained within the specified + * 'timeout', returns kStatus_OSA_Error if any errors occur during waiting, + * returns kStatus_OSA_Idle if the mutex is not available and 'timeout' is + * not exhausted, because wait functions should not block with bare metal. + * + *END**************************************************************************/ +osa_status_t OSA_MutexLock(mutex_t *pMutex, uint32_t timeout) +{ + uint32_t currentTime; + + assert(pMutex); + + /* Always check first. Deal with timeout only if not available. */ + if (pMutex->isLocked == false) + { + /* Get the lock and return success */ + INT_SYS_DisableIRQGlobal(); + pMutex->isLocked = true; + pMutex->isWaiting = false; + INT_SYS_EnableIRQGlobal(); + return kStatus_OSA_Success; + } + else + { + if (0 == timeout) + { + /* If timeout is 0 and mutex is not available, return kStatus_OSA_Timeout. */ + return kStatus_OSA_Timeout; + } + else if (pMutex->isWaiting) + { + /* Check for timeout */ + currentTime = OSA_TimeGetMsec(); + if (pMutex->timeout < time_diff(pMutex->time_start, currentTime)) + { + INT_SYS_DisableIRQGlobal(); + pMutex->isWaiting = false; + INT_SYS_EnableIRQGlobal(); + return kStatus_OSA_Timeout; + } + } + else if (timeout != OSA_WAIT_FOREVER) /* If dont't wait forever, start timer. */ + { + /* Start the timeout counter */ + INT_SYS_DisableIRQGlobal(); + pMutex->isWaiting = true; + INT_SYS_EnableIRQGlobal(); + pMutex->time_start = OSA_TimeGetMsec(); + pMutex->timeout = timeout; + } + } + + return kStatus_OSA_Idle; +} + +/*FUNCTION********************************************************************** + * + * Function Name : OSA_MutexUnlock + * Description : This function is used to unlock a mutex. + * + *END**************************************************************************/ +osa_status_t OSA_MutexUnlock(mutex_t *pMutex) +{ + assert(pMutex); + + INT_SYS_DisableIRQGlobal(); + pMutex->isLocked = false; + INT_SYS_EnableIRQGlobal(); + + return kStatus_OSA_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : OSA_MutexDestroy + * Description : This function is used to destroy a mutex. + * Return kStatus_OSA_Success if the lock object is destroyed successfully, otherwise + * return kStatus_OSA_Error. + * + *END**************************************************************************/ +osa_status_t OSA_MutexDestroy(mutex_t *pMutex) +{ + assert(pMutex); + + return kStatus_OSA_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : OSA_EventCreate + * Description : This function is used to create a event object. Return + * kStatus_OSA_Success if create successfully, otherwise return kStatus_OSA_Error. + * + *END**************************************************************************/ +osa_status_t OSA_EventCreate(event_t *pEvent, osa_event_clear_mode_t clearMode) +{ + assert(pEvent); + + pEvent->isWaiting = false; + pEvent->flags = 0; + pEvent->clearMode = clearMode; + pEvent->time_start = 0u; + pEvent->timeout = 0u; + + return kStatus_OSA_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : OSA_EventWait + * Description : This function checks the event's status, if it meets the wait + * condition, return kStatus_OSA_Success, otherwise, timeout will be used for + * wait. The parameter timeout indicates how long should wait in milliseconds. + * Pass OSA_WAIT_FOREVER to wait indefinitely, pass 0 will return the value + * kStatus_OSA_Timeout immediately if wait condition is not met. The event flags + * will be cleared if the event is auto clear mode. Flags that wakeup waiting + * task could be obtained from the parameter setFlags. + * This function returns kStatus_OSA_Success if wait condition is met, returns + * kStatus_OSA_Timeout if wait condition is not met within the specified + * 'timeout', returns kStatus_OSA_Error if any errors occur during waiting, + * returns kStatus_OSA_Idle if wait condition is not met and 'timeout' is + * not exhausted, because wait functions should not block with bare metal. + * + *END**************************************************************************/ +osa_status_t OSA_EventWait(event_t *pEvent, + event_flags_t flagsToWait, + bool waitAll, + uint32_t timeout, + event_flags_t *setFlags) +{ + uint32_t currentTime; + + assert(pEvent); + assert(setFlags); + + osa_status_t retVal = kStatus_OSA_Idle; + + *setFlags = pEvent->flags & flagsToWait; + + /* Check the event flag first, if does not meet wait condition, deal with timeout. */ + if ((((!waitAll) && (*setFlags))) || (*setFlags == flagsToWait)) + { + INT_SYS_DisableIRQGlobal(); + pEvent->isWaiting = false; + if(kEventAutoClear == pEvent->clearMode) + { + pEvent->flags &= ~flagsToWait; + } + INT_SYS_EnableIRQGlobal(); + return kStatus_OSA_Success; + } + else + { + if (0 == timeout) + { + /* If timeout is 0 and wait condition is not met, return kStatus_OSA_Timeout. */ + return kStatus_OSA_Timeout; + } + else if (pEvent->isWaiting) + { + /* Check for timeout */ + currentTime = OSA_TimeGetMsec(); + if (pEvent->timeout < time_diff(pEvent->time_start, currentTime)) + { + INT_SYS_DisableIRQGlobal(); + pEvent->isWaiting = false; + INT_SYS_EnableIRQGlobal(); + retVal = kStatus_OSA_Timeout; + } + } + else if(timeout != OSA_WAIT_FOREVER) /* If no timeout, don't start the timer */ + { + /* Start the timeout counter */ + INT_SYS_DisableIRQGlobal(); + pEvent->isWaiting = true; + INT_SYS_EnableIRQGlobal(); + pEvent->time_start = OSA_TimeGetMsec(); + pEvent->timeout = timeout; + } + } + + return retVal; +} + +/*FUNCTION********************************************************************** + * + * Function Name : OSA_EventSet + * Description : Set one or more event flags of an event object. + * Return kStatus_OSA_Success if set successfully, kStatus_OSA_Error if failed. + * + *END**************************************************************************/ +osa_status_t OSA_EventSet(event_t *pEvent, event_flags_t flagsToSet) +{ + assert(pEvent); + /* Set flags ensuring atomic operation */ + INT_SYS_DisableIRQGlobal(); + pEvent->flags |= flagsToSet; + INT_SYS_EnableIRQGlobal(); + + return kStatus_OSA_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : OSA_EventClear + * Description : Clear one or more event flags of an event object. + * Return kStatus_OSA_Success if clear successfully, kStatus_OSA_Error if failed. + * + *END**************************************************************************/ +osa_status_t OSA_EventClear(event_t *pEvent, event_flags_t flagsToClear) +{ + assert(pEvent); + /* Clear flags ensuring atomic operation */ + INT_SYS_DisableIRQGlobal(); + pEvent->flags &= ~flagsToClear; + INT_SYS_EnableIRQGlobal(); + + return kStatus_OSA_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : OSA_EventDestroy + * Description : This function is used to destroy a event object. Return + * kStatus_OSA_Success if the event object is destroyed successfully, otherwise + * return kStatus_OSA_Error. + * + *END**************************************************************************/ +osa_status_t OSA_EventDestroy(event_t *pEvent) +{ + assert(pEvent); + + return kStatus_OSA_Success; +} + +/* The task APIs are only available if TASK_MAX_NUM>0. */ +#if (TASK_MAX_NUM > 0) + +/* Global variales for task. */ +static task_handler_t g_curTask; /* Current task. */ + +/* + * All task control blocks in g_taskControlBlockPool will be linked as a + * list, and the list is managed by the pointer g_freeTaskControlBlock. + */ +static task_control_block_t g_taskControlBlockPool[TASK_MAX_NUM]; + +/* + * Pointer to the free task control blocks. To create a task, we should get + * task control block from this pointer. When task is destroyed, the control + * block will be returned and managed by this pointer. + */ +static task_control_block_t *g_freeTaskControlBlock; + +/* Head node of task list, all tasks will be linked to this head node. */ +static task_control_block_t g_taskListHead; + +/*FUNCTION********************************************************************** + * + * Function Name : task_init + * Description : This function is used to initialize bare metal's task system, + * it will prepare task control block pool and initialize corresponding + * structures. This function should be called before creating any tasks. + * + *END**************************************************************************/ +void task_init(void) +{ + int32_t i = TASK_MAX_NUM-1; + + g_taskControlBlockPool[i].next = NULL; + + while (i--) + { + /* Link all task control blocks to a list. */ + g_taskControlBlockPool[i].next = &g_taskControlBlockPool[i+1]; + } + + g_freeTaskControlBlock = g_taskControlBlockPool; + + /* Initialize task list. */ + g_taskListHead.next = &g_taskListHead; + g_taskListHead.prev = &g_taskListHead; +} + +/*FUNCTION********************************************************************** + * + * Function Name : OSA_TaskCreate + * Description : This function will register the task function and parameter + * to task list, so that the task functions can be called in turn. Return + * kStatus_OSA_Success if register successfully, otherwise return kStatus_OSA_Error; + * + *END**************************************************************************/ +osa_status_t OSA_TaskCreate(task_t task, + uint8_t *name, + uint16_t stackSize, + task_stack_t *stackMem, + uint16_t priority, + task_param_t param, + bool usesFloat, + task_handler_t *handler) +{ + task_control_block_t *p_newTaskControlBlock; + task_control_block_t *p_taskListTail; + + if (!g_freeTaskControlBlock) + { + /* No more task control blocks can be got. */ + return kStatus_OSA_Error; + } + else + { + /* Get new task control block from pool. */ + p_newTaskControlBlock = g_freeTaskControlBlock; + g_freeTaskControlBlock = g_freeTaskControlBlock->next; + /* Set task entry and parameter.*/ + p_newTaskControlBlock->p_func = task; + p_newTaskControlBlock->param = param; + /* Add p_newTaskControlBlock to the tail of task list. */ + p_taskListTail = g_taskListHead.prev; + p_taskListTail->next = p_newTaskControlBlock; + p_newTaskControlBlock->next = &g_taskListHead; + g_taskListHead.prev = p_newTaskControlBlock; + p_newTaskControlBlock->prev = p_taskListTail; + /* Task handler is pointer of task control block. */ + *handler = p_newTaskControlBlock; + + return kStatus_OSA_Success; + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : OSA_TaskDestroy + * Description : This function will remove task control block from task list, + * so that the task functions will not called by anymore. + * Return kStatus_OSA_Success if successfully, otherwise return kStatus_OSA_Error; + * + *END**************************************************************************/ +osa_status_t OSA_TaskDestroy(task_handler_t handler) +{ + assert(handler); + /* Remove task control block from task list. */ + handler->prev->next = handler->next; + handler->next->prev = handler->prev; + + /* + * If current task is destroyed, then g_curTask will point to the previous + * task, so that the subsequent tasks could be called. Check the function + * OSA_Start for more details. + */ + if (handler == g_curTask) + { + g_curTask = handler->prev; + } + + /* Put task control block back to pool. */ + handler->prev = NULL; + handler->next = g_freeTaskControlBlock; + g_freeTaskControlBlock = handler; + + return kStatus_OSA_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : OSA_TaskYield + * Description : This function is not implement with bare metal. + * + *END**************************************************************************/ +osa_status_t OSA_TaskYield(void) +{ + return kStatus_OSA_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : OSA_TaskGetHandler + * Description : This function is used to get current active task's handler. + * + *END**************************************************************************/ +task_handler_t OSA_TaskGetHandler(void) +{ + return g_curTask; +} + +/*FUNCTION********************************************************************** + * + * Function Name : OSA_TaskGetPriority + * Description : This function is not implement with bare metal. + * + *END**************************************************************************/ +uint16_t OSA_TaskGetPriority(task_handler_t handler) +{ + return 0; +} + +/*FUNCTION********************************************************************** + * + * Function Name : OSA_TaskSetPriority + * Description : This function is not implement with bare metal. + * + *END**************************************************************************/ +osa_status_t OSA_TaskSetPriority(task_handler_t handler, uint16_t priority) +{ + return kStatus_OSA_Success; +} +#endif + +/*FUNCTION********************************************************************** + * + * Function Name : OSA_MsgQCreate + * Description : This function is used to create a message queue. + * Return the handle to the message queue if create successfully, otherwise + * return 0. + * + *END**************************************************************************/ +msg_queue_handler_t OSA_MsgQCreate(msg_queue_t *queue, + uint16_t message_number, + uint16_t message_size) +{ + assert(queue); + + queue->number = message_number; + queue->size = message_size; + queue->head = 0; + queue->tail = 0; + queue->isEmpty = true; + + if(kStatus_OSA_Success == OSA_SemaCreate(&queue->queueSem, 0)) + { + return queue; + } + else + { + return NULL; + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : OSA_MsgQPut + * Description : This function is used to put a message to a message queue. + * Return kStatus_OSA_Success if the message is put successfully, otherwise + * return kStatus_OSA_Error. + * + *END**************************************************************************/ +osa_status_t OSA_MsgQPut(msg_queue_handler_t handler, void* pMessage) +{ + assert(handler); + uint32_t *from_ptr, *to_ptr; + uint16_t msgSize; + + /* Check that there is room in the queue */ + INT_SYS_DisableIRQGlobal(); + if((handler->tail != handler->head) || (handler->isEmpty)) + { + from_ptr = (uint32_t*)pMessage; + to_ptr = &handler->queueMem[handler->tail * handler->size]; + + /* Copy entire message into the queue, based on the size configured at creation */ + msgSize = handler->size; + while(msgSize--) + { + *to_ptr++ = *from_ptr++; + } + + /* Adjust tail pointer and wrap in case the end of the buffer is reached */ + ++handler->tail; + if(handler->tail == handler->number) + { + handler->tail = 0; + } + + /* If queue was empty, clear the empty flag and signal that it is not empty anymore */ + if(handler->isEmpty) + { + handler->isEmpty = false; + OSA_SemaPost(&handler->queueSem); + } + INT_SYS_EnableIRQGlobal(); + + return kStatus_OSA_Success; + } + else + { + INT_SYS_EnableIRQGlobal(); + return kStatus_OSA_Error; + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : OSA_MsgQGet + * Description : This function checks the queue's status, if it is not empty, + * get message from it and return kStatus_OSA_Success, otherwise, timeout will + * be used for wait. The parameter timeout indicates how long should wait in + * milliseconds. Pass OSA_WAIT_FOREVER to wait indefinitely, pass 0 will return + * kStatus_OSA_Timeout immediately if queue is empty. + * This function returns kStatus_OSA_Success if message is got successfully, + * returns kStatus_OSA_Timeout if message queue is empty within the specified + * 'timeout', returns kStatus_OSA_Error if any errors occur during waiting, + * returns kStatus_OSA_Idle if message queue is empty and 'timeout' is + * not exhausted, because wait functions should not block with bare metal. + * + *END**************************************************************************/ +osa_status_t OSA_MsgQGet(msg_queue_handler_t handler, + void *pMessage, + uint32_t timeout) +{ + assert(handler); + osa_status_t retVal = kStatus_OSA_Error; + uint32_t *from_ptr, *to_ptr; + uint16_t msgSize; + + INT_SYS_DisableIRQGlobal(); + /* Check if the queue is not empty */ + if(!handler->isEmpty) + { + from_ptr = &handler->queueMem[handler->head * handler->size]; + to_ptr = (uint32_t*)(pMessage); + + /* Copy entire message into the queue, based on the size configured at creation */ + msgSize = handler->size; + while(msgSize--) + { + *to_ptr++ = *from_ptr++; + } + + /* Adjust head pointer and wrap in case the end of the buffer is reached */ + ++handler->head; + if(handler->head == handler->number) + { + handler->head = 0; + } + + /* If queue was empty, clear the empty flag and signal that it is not empty anymore */ + if(handler->head == handler->tail) + { + handler->isEmpty = true; + /* Set semapohre to 0 because the queue is empty. */ + (void)OSA_SemaWait(&handler->queueSem, 0); + } + INT_SYS_EnableIRQGlobal(); + + retVal = kStatus_OSA_Success; + } + else + { + INT_SYS_EnableIRQGlobal(); + /* Wait for the semaphore if the queue was empty */ + retVal = OSA_SemaWait(&handler->queueSem, timeout); + } + + return retVal; +} + +/*FUNCTION********************************************************************** + * + * Function Name : OSA_MsgQDestroy + * Description : This function is used to destroy the message queue. + * Return kStatus_OSA_Success if the message queue is destroyed successfully, + * otherwise return kStatus_OSA_Error. + * + *END**************************************************************************/ +osa_status_t OSA_MsgQDestroy(msg_queue_handler_t handler) +{ + assert(handler); + return OSA_SemaDestroy(&handler->queueSem); +} + +/*FUNCTION********************************************************************** + * + * Function Name : OSA_MemAlloc + * Description : This function is used to allocate amount of memory in bytes. + * Return the pointer to the memory if success, otherwise return NULL; + * + *END**************************************************************************/ +void * OSA_MemAlloc(size_t size) +{ + return malloc(size); +} + +/*FUNCTION********************************************************************** + * + * Function Name : OSA_MemAllocZero + * Description : This function is used to allocate amount of memory in bytes + * and initializes it to 0. + * Return the pointer to the memory if success, otherwise return NULL; + * + *END**************************************************************************/ +void * OSA_MemAllocZero(size_t size) +{ + return calloc(1, size); +} + +/*FUNCTION********************************************************************** + * + * Function Name : OSA_MemFree + * Description : This function is used to free the memory previously allocated. + * + *END**************************************************************************/ +osa_status_t OSA_MemFree(void *ptr) +{ + free(ptr); + return kStatus_OSA_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : OSA_TimeDelay + * Description : This function is used to delay for a number of milliseconds. + * + *END**************************************************************************/ +void OSA_TimeDelay(uint32_t delay) +{ + uint32_t currTime, timeStart; + + timeStart = OSA_TimeGetMsec(); + + do { + currTime = OSA_TimeGetMsec(); /* Get current time stamp */ + } while (delay >= time_diff(timeStart, currTime)); +} + +/*FUNCTION********************************************************************** + * + * Function Name : OSA_TimeGetMsec + * Description : This function gets current time in milliseconds. + * + *END**************************************************************************/ +uint32_t OSA_TimeGetMsec(void) +{ + return LPTMR_HAL_GetCounterValue(BM_LPTMR_BASE); +} + +/*FUNCTION********************************************************************** + * + * Function Name : interrupt_handler_register + * Description : This function is used to install interrupt handler. + * For bare metal, this function is empty. + * + *END**************************************************************************/ +osa_status_t OSA_InstallIntHandler (int32_t IRQNumber, + void (*handler)(void)) +{ + INT_SYS_InstallHandler((IRQn_Type)IRQNumber, handler); + return kStatus_OSA_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : OSA_EnterCritical + * Description : This function is used to ensure some code will not be preempted. + * + *END**************************************************************************/ +void OSA_EnterCritical(osa_critical_section_mode_t mode) +{ + if (kCriticalDisableInt == mode) + { + INT_SYS_DisableIRQGlobal(); + } + else + { + return; + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : OSA_ExitCritical + * Description : This function is used to exit critical section. + * + *END**************************************************************************/ +void OSA_ExitCritical(osa_critical_section_mode_t mode) +{ + if (kCriticalDisableInt == mode) + { + INT_SYS_EnableIRQGlobal(); + } + else + { + return; + } +} + +/*FUNCTION********************************************************************** + * + * Function Name : OSA_Init + * Description : This function is used to setup the basic services, it should + * be called first in function main. Return kStatus_OSA_Success if services + * are initialized successfully, otherwise return kStatus_OSA_Error. + * + *END**************************************************************************/ +osa_status_t OSA_Init(void) +{ +#if (TASK_MAX_NUM > 0) + task_init(); +#endif + + /* + * Setup LP Timer for timeout and delay. + * Use 1kHz LPO as clock source, disable prescaler, freerun mode. + */ + + CLOCK_SYS_EnableLptimerClock(BM_LPTMR_INSTANCE); + + LPTMR_HAL_SetTimerModeMode(BM_LPTMR_BASE, kLptmrTimerModeTimeCounter); + + LPTMR_HAL_SetFreeRunningCmd(BM_LPTMR_BASE, true); + + LPTMR_HAL_SetPrescalerCmd(BM_LPTMR_BASE, false); + + LPTMR_HAL_SetPrescalerClockSourceMode(BM_LPTMR_BASE, kLptmrPrescalerClockSourceLpo); + + LPTMR_HAL_SetIntCmd(BM_LPTMR_BASE,false); + + LPTMR_HAL_Enable(BM_LPTMR_BASE); + + return kStatus_OSA_Success; +} + +/*FUNCTION********************************************************************** + * + * Function Name : OSA_Start + * Description : This function is used to start RTOS scheduler. + * + *END**************************************************************************/ +osa_status_t OSA_Start(void) +{ +#if (TASK_MAX_NUM > 0) + g_curTask = &g_taskListHead; + + for(;;) + { + if (g_curTask->p_func) + { + g_curTask->p_func(g_curTask->param); + } + g_curTask = g_curTask->next; + } +#else + for(;;) + { + } +#endif +} + +#if (TASK_MAX_NUM > 0) +/*FUNCTION********************************************************************** + * + * Function Name : OSA_PollAllOtherTasks + * Description : This function calls all task functions except current task + * one time. It is only for bare metal. + * + *END**************************************************************************/ +void OSA_PollAllOtherTasks(void) +{ + task_handler_t curTaskSave = g_curTask; + g_curTask = g_taskListHead.next; + + while ((g_curTask->p_func) && (g_curTask!=curTaskSave)) + { + g_curTask->p_func(g_curTask->param); + g_curTask = g_curTask->next; + } + g_curTask = curTaskSave; +} +#endif + +/******************************************************************************* + * EOF + ******************************************************************************/ diff --git a/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/utilities/src/fsl_os_abstraction_mbed.c b/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/osa/src/fsl_os_abstraction_mbed.c similarity index 100% rename from libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/utilities/src/fsl_os_abstraction_mbed.c rename to libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/osa/src/fsl_os_abstraction_mbed.c diff --git a/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/utilities/src/fsl_misc_utilities.c b/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/utilities/src/fsl_misc_utilities.c new file mode 100644 index 0000000000..f9f1f77abf --- /dev/null +++ b/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/utilities/src/fsl_misc_utilities.c @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * o Redistributions of source code must retain the above copyright notice, this list + * of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright notice, this + * list of conditions and the following disclaimer in the documentation and/or + * other materials provided with the distribution. + * + * o Neither the name of Freescale Semiconductor, Inc. nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include "fsl_misc_utilities.h" + +#if (defined(KEIL)) + +/*FUNCTION********************************************************************** + * + * Function Name : __aeabi_assert + * Description : called by assert in KEIL + * This function is called by the assert function in KEIL. + * + *END**************************************************************************/ +void __aeabi_assert(const char *expr, const char *file, int line) +{ + printf("assert failed:%s, file %s:%d\r\n",expr,file,line); +} + +#elif (defined(KDS)) + +/*FUNCTION********************************************************************** + * + * Function Name : _isatty + * Description : used to enable the overwrite of the _write + * This function is used to enable the overwrite of the _write. + * + *END**************************************************************************/ +int _isatty (int fd) +{ + return 1; +} + +#endif + +/******************************************************************************* + * EOF + ******************************************************************************/ diff --git a/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/utilities/sw_timer.h b/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/utilities/sw_timer.h deleted file mode 100644 index fbd4660517..0000000000 --- a/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KPSDK_MCUS/TARGET_KPSDK_CODE/utilities/sw_timer.h +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (c) 2013 - 2014, Freescale Semiconductor, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * o Redistributions of source code must retain the above copyright notice, this list - * of conditions and the following disclaimer. - * - * o Redistributions in binary form must reproduce the above copyright notice, this - * list of conditions and the following disclaimer in the documentation and/or - * other materials provided with the distribution. - * - * o Neither the name of Freescale Semiconductor, Inc. nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#if !defined(__SW_TIMER_H__) -#define __SW_TIMER_H__ - -#include -#include - -/*! @addtogroup sw_timer Software Timer - * @brief This module is used to interface with Abstract Timer HAL to generate periodical timeouts - * required through different modules of the AOA protocol. This block will be based on 1ms - * ticks for all the timeout calculations. The HAL Interface block used to communicate with - * this must have the same 1ms timeout configured. This module can generate different - * software timer channels based on the same 1ms. - */ -/*! @{*/ - -/*! Definition of the possible status of a software channel timer. */ -typedef enum SwTimerChannelStatus -{ - kSwTimerChannelExpired = 0x00, /*!< Indicates the timer channel has counted the given ms*/ - kSwTimerChannelStillCounting = 0x01, /*!< Indicates the timeout of the channel has not expired - and the timer is still counting.*/ - kSwTimerChannelIsDisable = 0x02, /*!< Indicates the timer channel is not reserved. */ - kSwTimerChannelNotAvailable = 0xFF /*!< Indicates there are not available channels to reserve - or the requested channel is not available.*/ -}sw_timer_channel_status_t; - -/*! List of status and errors. */ -enum _sw_timer_errors -{ - kSwTimerStatusSuccess, /*!< The execution was successful.*/ - kSwTimerStatusFail, /*!< The execution failed.*/ - kSwTimerStatusInvalidChannel /*!< The given channel is not valid. Valid channels are 0 to - (SW_TIMER_NUMBER_CHANNELS - 1). */ -}; - -/*! - * Data type of the counter of each timer channel. If it is an int8_t the counter will count - * up to 127ms, int16_t up to 32767ms and int32_t up to 2147483647ms. - */ -typedef int32_t time_counter_t; - -/*! Max timeout value according to size of the time counter */ -enum sw_timer_timeouts -{ - kSwTimerMaxTimeout = 2147483647 -}; - -/*! - * Data type of the free running counter. This data type should be unsigned and will count up to - * 255ms if it is uint8_t, 65535ms for uint16_t and 4294967295ms for uint32_t. - */ -typedef uint32_t time_free_counter_t; - -#if defined(__cplusplus) -extern "C" { -#endif /* __cplusplus*/ - -/*! - * @brief Initializes the software timer module. Prepares variables and HAL layer to provide timer - * services. Starts the free running counter which will be available to get its value any - * time while the service is running; it is useful whenever a module wants to keep track of - * time, but do not wants to reserve a channel. - * - * @return status_t Returns software timer status after initialization. - * @retval kSwTimerStatusSuccess The initialization was successful and the software timer is ready - * to provide services. - * @retval kSwTimerStatusFail The initialization failed. - */ -uint32_t sw_timer_init_service(void); - -/*! - * @brief Deinitializes the software timer module. Shutdown HAL layer, so no timer service can be - * provided after the execution of this function. - * - * @return void - */ -void sw_timer_shutdown_service(void); - -/*! - * @brief Reserves a free timer channel to be used by any module and returns its identifier. - * - * @return uint8_t Returns the number of the channel that was reserved. - * @retval Any value between 0 and SW_TIMER_NUMBER_CHANNELS is a valid channel. It indicates the - * channel was reserved and can be used. - * @retval kSwTimerChannelNotAvailable If there is not any available channel, because all - * channels are already reserved. - */ -uint8_t sw_timer_reserve_channel(void); - -/*! - * @brief Returns the actual status of the given timer channel. The timer has to be previously - * started to return a valid status. - * - * @param timerChannel [in] Indicates the timer channel which status is going to be returned. - * - * @return sw_timer_channel_status_t Current status of the given timer channel. - * @retval kSwTimerChannelExpired Indicates the timer channel has counted the given ms. - * @retval kSwTimerChannelStillCounting Indicates the timeout of the channel has not expired and - the timer is still counting. - * @retval kSwTimerChannelIsDisable Indicates the timer channel is not reserved. - * @retval kSwTimerChannelNotAvailable Indicates the timer channel is invalid. - */ -sw_timer_channel_status_t sw_timer_get_channel_status(uint8_t timerChannel); - -/*! - * @brief Starts the count down of the given timer channel. The timer channel has to be previously - * reserved. - * - * @param timerChannel [in] Indicates the timer channel that is going to be started. - * @param timeout [in] Time in ms that the timer channel will count. The timeout should be - a multiple of count unit of the timer, otherwise it will be taken - the integer part of the division and the exact count will not be - achieved - * - * @return status_t Reports failures in the execution of the function. - * @retval kSwTimerStatusSuccess A channel was started successfully. - * @retval kSwTimerStatusInvalidChannel The timer channel is invalid, it does not exist. - */ -uint32_t sw_timer_start_channel(uint8_t timerChannel, time_counter_t timeout); - -/*! - * @brief Releases the given timer channel, so it can be used by someone else. - * - * @param timerChannel [in] Identifier of the timer channel. - * - * @return status_t Reports failures in the execution of the function. - * @retval kSwTimerStatusSuccess A channel was released successfully. - * @retval kSwTimerStatusInvalidChannel The timer channel is invalid, it does not exist. - */ -uint32_t sw_timer_release_channel(uint8_t timerChannel); - -/*! - * @brief Gets the current value of the free running counter. Any module can keep track of the time - * by reading this counter and calculates time difference. No reservation of timer channel - * is needed. Consider for calculations that when the counter overflows it will start from - * 0 again. - * - * @return time_free_counter_t Returns current count of the free running counter. - */ -time_free_counter_t sw_timer_get_free_counter(void); - -/*! - * @brief This function is called every 1ms by the interruption and update count down values of all - * timer channels. - * - * @return void - */ -void sw_timer_update_counters(void); - - -#if defined(__cplusplus) -} -#endif /* __cplusplus*/ -/*! @}*/ -/*Group sw_timer*/ - -#endif /* __SW_TIMER_H__ */ -/******************************************************************************* - * EOF - ******************************************************************************/ -