/**
 * \file    sync.h
 * \brief   System synchronization definitions
 *
 * \par     Copyright (c) 2018 UWE Technologies Corp., Ltd. All Rights Reserved.
 * \author  James
 * \date    2018-07-23
 * \version 
 * 
 * \history 
 *  Date        Note
 *  2018-07-23  Original Creation
 * 
 */
 
#ifndef __SYNC_H_
#define __SYNC_H_


#include "arch.h"
#include "types.h"
#include "drv_interrupt.h"

#ifndef SYS_FREERTOS_ENABLED
    #define SYS_FREERTOS_ENABLED    (0)
#endif

#define SYNC_MAX_DELAY  (unsigned int)0xffffffffUL

typedef struct sync_info_s
{
    u32_t sys_init_flag:1;
    u32_t ext_isr_pending:1;
    u32_t reserved:30;
}sync_info_t;

extern volatile sync_info_t g_sync_info;

#define sync_sys_init_flag_set(flg)     (g_sync_info.sys_init_flag=flg)
#define sync_sys_init_flag_get()        (g_sync_info.sys_init_flag)

#define sync_ext_isr_pending_set(flg)   (g_sync_info.ext_isr_pending=flg)
#define sync_ext_isr_pending_get()      (g_sync_info.ext_isr_pending)

void sync_sys_init();
void sync_sys_init_done();

#if (SYS_FREERTOS_ENABLED)

/* Kernel includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"
#include "drv_interrupt.h"

#define sync_enter_critical() \
    UBaseType_t uxSavedInterruptStatus = 0; \
    if (!sync_sys_init_flag_get()) { \
        if (sync_ext_isr_pending_get()) { \
            uxSavedInterruptStatus = taskENTER_CRITICAL_FROM_ISR(); \
        } \
        else { \
            taskENTER_CRITICAL(); \
        } \
    }

#define sync_exit_critical() \
    if (!sync_sys_init_flag_get()) { \
        if (sync_ext_isr_pending_get()) { \
            taskEXIT_CRITICAL_FROM_ISR( uxSavedInterruptStatus ); \
        } \
        else { \
            taskEXIT_CRITICAL(); \
        } \
    }

#define sync_mutex_create()             xSemaphoreCreateMutex()

#define sync_mutex_take(lock,timeout) \
    if (!sync_sys_init_flag_get()) { \
        xSemaphoreTake(lock,timeout); \
    }

#define sync_mutex_give(lock) \
    if (!sync_sys_init_flag_get()) { \
        xSemaphoreGive(lock); \
    }

#define sync_mutex_delete(lock)         vSemaphoreDelete(lock)


#else

#define sync_enter_critical() \
    u32_t intr_local = DRV_INTR_GLOBAL_GET(); \
    if (!sync_sys_init_flag_get()) { \
        DRV_INTR_GLOBAL_DISABLE(); \
    }

#define sync_exit_critical() \
    if (!sync_sys_init_flag_get()) { \
        DRV_INTR_GLOBAL_SET(intr_local); \
    }

#define sync_mutex_create()             (0)
#define sync_mutex_take(lock,timeout)
#define sync_mutex_give(lock)
#define sync_mutex_delete(lock)

#endif


#endif /* #ifndef __SYNC_H_ */

