/************************************************************************/
/* Copyright 2002-2016 MBARI											*/
/************************************************************************/
/* Summary  : Definitions for Multitasking library for OASIS5 on PIC32	*/
/* Filename : otask.h													*/
/* Author   : Robert Herlien (rah)										*/
/* Project  : OASIS Mooring Replacement (OASIS5)						*/
/* Revision: 1.0														*/
/* Created  : 07/06/2016 from oasis3/4 task.h							*/
/*																	    */
/* MBARI provides this documentation and code "as is", with no warranty,    */
/* express or implied, of its quality or consistency. It is provided without*/
/* support and without obligation on the part of the Monterey Bay Aquarium  */
/* Research Institute to assist in its use, correction, modification, or    */
/* enhancement. This information should not be published or distributed to  */
/* third parties without specific written permission from MBARI.            */
/*									    								*/
/************************************************************************/
/* Modification History:												*/
/* 14oct2002 rah - OASIS3 task.h created from OASIS io.h				*/
/* 6jul2016 rah - OASIS5 otask.h created from OASIS3 task.h				*/
/* Renamed to otask.h to avoid conflict with FreeRTOS task.h			*/
/************************************************************************/
#ifndef OTASK_H
#define OTASK_H			1

#include <FreeRTOS.h>
#include <task.h>						/* FreeRTOS/include task.h		*/
#include <FreeRTOSConfig.h>
#include <mbariTypes.h>
#include <mbariConst.h>
#include <timer.h>						/* Oasis defns of tick rate		*/
#include <olist.h>						/* OASIS linked list definitions*/


#ifdef __DEBUG							/* Defined when using MPLab debugger*/
#define DRV_STACK_WORDS		1024		/* Driver task stack in 32bit words*/
#else
#define DRV_STACK_WORDS		512			/* Driver task stack in 32bit words*/
#endif

#define SCHED_STACK_WORDS	384
#define MISC_STACK_WORDS	384


/****************************************/
/* Type definitions for Task Library	*/
/****************************************/

typedef void		(*FuncPtr)();		/* Function pointer		    */

typedef TaskHandle_t Tid;				/* Task ID					*/

#define NULLTID		((Tid)0)
#define NULLTASK	((TaskHandle_t)0)
#define NULLFUNC	((FuncPtr)0)

typedef enum
	{IDLE_PRIO=0, SCHED_PRIO, DRVR_PRIO, COMPL_PRIO, KERNEL_PRIO, PWRFAIL_PRIO}
	TaskPriority;

#define MAX_TASK_PRIO		PWRFAIL_PRIO

typedef enum							/************************************/
{										/* Task State type		    		*/
	NOT_OURS = 0,						/* Task that we're not keeping track of*/
    READY,								/* Either ready or actually running	*/
    PENDING,							/* Pending on a semaphore			*/
    DELAY,								/* Waiting for vTaskDelay()			*/
    ZOMBIE								/* Being killed						*/
}TaskState;								/************************************/

typedef enum
	{ConsoleP=0, DrvrP, State, StateParm, Malloc1, Malloc2} ThreadLocalIndex;


typedef struct task_node				/************************************/
{										/* Struct to locate TaskDesc's	    */
    Node		 tn_link;				/* For linked lists				    */
    TaskHandle_t tn_td;					/* Ptr to TaskDesc				    */
} TaskNode;								/************************************/


/****************************************/
/*	Macros								*/
/****************************************/

#if (configUSE_PREEMPTION == 0)
#define dispatch()			taskYIELD()
#define taskLock()
#define taskUnlock()
#else
#define dispatch()
#define taskLock()			vTaskSuspendAll()
#define taskUnlock() 		vTaskResumeAll()
#endif

#define task_get()			xTaskGetCurrentTaskHandle()
#define task_delay_ms(ms)	task_delay(ms/MS_PER_TICK)
#define task_find(name)		xTaskGetHandle(name)
#define taskCriticalEntry()	vTaskSuspendAll()
#define taskCriticalExit()	vTaskResumeAll()

#define MAX_TICK_SECS		(NAT32_MAX/TICKS_PER_SEC)


/****************************************/
/*	Function Declarations				*/
/****************************************/

TaskHandle_t task_create(void (*entryPt)(void *), void *arg, char *name,
						 Nat16 stackDepth, Nat32 priority);

void		task_delay(TickType_t ticks);
void		taskKill(TaskHandle_t td);
void		delay_secs(Nat32 secs);

#endif	/* OTASK_H */
