/*
 * 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_UCOSIII_H__)
#define __FSL_OS_ABSTRACTION_UCOSIII_H__

#include "os.h"

/*!
* @addtogroup os_abstraction_ucosiii
* @{
*/

/*******************************************************************************
 * Declarations
 ******************************************************************************/
/*! @brief Constant to pass as timeout value in order to wait indefinitely. */
#define kSyncWaitForever  0xFFFFFFFFU

/*! @brief Type for an event group object in uCOS-III */
typedef struct {
    OS_FLAG_GRP      group;      /*!< uCOS-III's event entity    */
    event_clear_type clearType;  /*!< Auto clear or manual clear */
} EVENT_UCOSIII;

#if (__FSL_RTOS_MSGQ_COPY_MSG__)
/*! @brief Type for message queue in uCOS-III */
typedef struct {
    OS_Q      queue; /*!< the message queue's control block                       */
    OS_MEM    mem;   /*!< control block for the memory where save the messages    */
    void     *msgs;  /*!< pointer to the memory where save the messages           */
    uint16_t  size;  /*!< size of the message in words                            */
} MSGQ_STRUCT_UCOSIII;
#endif

/*! @brief Type for a task handler, returned by the task_create function.*/
typedef OS_TCB* task_handler_t;

/*! @brief Type for a task stack.*/
typedef CPU_STK task_stack_t;

/*! @brief Type for a task pointer.*/
typedef void (* task_t)(void* start);

/*! @brief Type for an synchronization object.*/
typedef OS_SEM   sync_object_t;

/*! @brief Type for a resource locking object.*/
typedef OS_MUTEX lock_object_t;

/*! @brief Type for an event flags group, bit 32 is reserved.*/
typedef OS_FLAGS event_group_t;

/*! @brief Type for an event group object */
typedef EVENT_UCOSIII  event_object_t;

/*! @brief Type for a message queue declaration and creation.*/
#if (__FSL_RTOS_MSGQ_COPY_MSG__)
typedef MSGQ_STRUCT_UCOSIII msg_queue_t;
#else
typedef OS_Q msg_queue_t;
#endif

/*! @brief Type for a message queue handler */
typedef msg_queue_t* msg_queue_handler_t;

/*! @brief Type for a message queue item.*/
typedef void*  msg_queue_item_t;


/*! @brief Macro passed to the task_destroy function to destroy the current task */
#define FSL_RTOS_CURRENT_TASK ((task_handler_t)OSTCBCurPtr)

/*!
* @name Thread management
* @{
*/

/*!
 * @brief Creates a task descriptor that is used to create the task with task_create.
 *
 * @param task The task function.
 * @param stackSize Number of elements in the stack for this task.
 * @param name String to assign to the task.
 * @param usesFloat Boolean that indicates whether the task uses the floating point unit.
 */
#define FSL_RTOS_TASK_DEFINE(task, stackSize, name, usesFloat)          \
    OS_TCB TCB_##task;                                                  \
    task_stack_t fslTaskStack_##task[(stackSize)/sizeof(task_stack_t)]; \
    uint8_t fslTaskName_##task[] = name;                                \
    bool fslTaskFloatUse_##task = usesFloat

/*!
* @name Thread management
* @{
*/

/*!
 * @brief Creates and sets the task to active.
 *
 * @param task The task function.
 * @param priority Initial priority of the task.
 * @param param Pointer to be passed to the task when it is created.
 * @param handler Returns the identifier to be used afterwards to destroy the task.
 * 
 * @retval kSuccess The task was successfully created.
 * @retval kError Creation of task failed.
 */
#define task_create(task, priority, param, handler)                 \
    (*(handler) = &(TCB_##task),                                    \
    __task_create(task,                                             \
                  fslTaskName_##task,                               \
                  sizeof(fslTaskStack_##task),                      \
                  fslTaskStack_##task,                              \
                  priority,                                         \
                  param,                                            \
                  fslTaskFloatUse_##task,                           \
                  handler))
/*@}*/


/*!
* @name Synchronization
* @{
*/

/*!
 * @brief Create the synchronization object. To be used instead of a standard
 *      declaration.
 *
 * @param obj The sync object to create.
 */
#define sync_object_declare(obj)    sync_object_t obj

/*@}*/

/*!
* @name Resource locking
* @{
*/

/*!
 * @brief Create the locking object. To be used instead of a standard
 *      declaration.
 *
 * @param obj The lock object to create.
 */
#define lock_object_declare(obj) lock_object_t obj

/*@}*/

/*!
* @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 elements in words.
 */
#if (__FSL_RTOS_MSGQ_COPY_MSG__)
#define MSG_QUEUE_DECLARE(name, number, size)            \
    uint32_t msgs##name[number*size];                    \
    msg_queue_t name = {                                 \
        .msgs = msgs##name                               \
    }
#else
#define MSG_QUEUE_DECLARE(name, number, size)   msg_queue_t name
#endif

/*@}*/

/*!
* @name Critical Sections
* @{
*/

/*! @brief Ensures the following code will not be preempted */
#define rtos_enter_critical OS_CRITICAL_ENTER

/*! @brief Allows preemption */
#define rtos_exit_critical  OS_CRITICAL_EXIT

/*@}*/

/*! @}*/

#endif /* __FSL_OS_ABSTRACTION_UCOSIII_H__*/
/*******************************************************************************
 * EOF
 ******************************************************************************/

