/**************************************************************************************************
 * Copyright (c) 2017 Epsilon Kran GmbH
 * Christophorusstraße 30, 5061 Elsbethen-Glasenbach, Austria. epsilon@palfinger.com
 *************************************************************************************************/
/**********************************************************************************************//**
 * \file base.h
 *
 * \latexonly \hypertarget{base}{} \endlatexonly
 *
 * * \brief base task class definition.
 *
 *
 *
 * \section base_sec Task Handling
 *
 * Each object of this type could be called cyclic by the object Handler.
 * The user doesn't need to handle the timing. Therefore are 4
 * functions available which could be derived:
 *  - \ref base.init
 *  - \ref base.pre
 *  - \ref base.work
 *  - \ref base.post
 *  - \ref base.idle
 *
 *
 *************************************************************************************************/


#ifndef INC_BASE_H_
#define INC_BASE_H_


/**************************************************************************************************
 *
 * I N C L U D E S
 *
 *************************************************************************************************/
#include "global.h"
#include "ptypes_tms570.h"
#include "EPS_Error.h"


/**************************************************************************************************
 *
 * D E F I N I T I O N S
 *
 *************************************************************************************************/
#define BASE_TIME               100         /* Runs per secound */


/**********************************************************************************************//**
 *
 * \brief Constructor of the base object
 *
 *  The constructor initializes the object memory
 *************************************************************************************************/
#define construct_base()    \
{ \
    &base_init, \
    &base_pre, \
    &base_work, \
    &base_post, \
    &base_idle, \
}


/*
 * TODO Fehlerbehandlung: Fehler nach oben durchreichen, Code normal weiter ausführen und auf Befehl von oben warten
 */
/**************************************************************************************************
 *
 * D A T A   S T R U C T U R E S
 *
 *************************************************************************************************/

struct base_s;
typedef EPS_ErrorType (*const fnc_base_objCall_t)(struct base_s* const self);


/**
 *
 * \brief base object structure
 *
 * Every base object need the information, defined in this structure. \n
 * The basic object only has an init routine and a constructor to gernate \n
 * the object and to initialize the parameters. \n
 *
 * \warning
 * Every variable pointer and method pointer in the struct has to be set by the constructor!
 *
 */
typedef struct base_s{
    /*
     * Methods of the Class
     */

    /**
     *
     * \brief init prototype of the base object
     *
     * Functions of the type \ref base.init are called until the initialization process is finished.
     * The given counter value gets increased every initialization run.
     * If the initialization is not finished it is possible to returns #EPS_E_BUSY.
     * After a #EPS_E_BUSY return code the function gets recalled until #EPS_E_OK is returned.
     *
     * \param void*                              This pointer to a \ref base object
     * \param ubyte4                             run counter of the initialization routine
     *
     * \return #EPS_ErrorType
     *
     * **************************************************************************************************
     *
     *
     * \note
     *   The initialization functions are so long called until all objects are initialized.
     *
     * \warning
     *   It is possible, that the function is recalled even if the return value #EPS_E_OK has been returned!
     *
     */
    fnc_base_objCall_t init;


    /**
     * \brief object prototype method
     *
     * The pre implementation of the class base is called before the base.work
     * is called. This interface allows cyclic manipulation of variables befor the
     * work task which holds the application.
     *
     * \param void*                              This pointer to the \ref base object memory
     * \return #EPS_ErrorType
     *
     * **************************************************************************************************
     *
     * \remarks
     *      This function is called before the work is called. Here usually the input variables
     *      are readed an provided to the application.
     *
     * \note
     *   The base.pre function is called cyclic ever specified period.
     *
     * \note
     *   If the function is overwritten, additional error codes could be returned
     *
     */
    fnc_base_objCall_t pre;


    /**
     * \brief object prototype method
     *
     * The work implementation of the class base is called after all base.pre
     * routines where called.
     * This interface allows cyclic manipulation of variables and performing an application.
     *
     * \param void*                              This pointer to the \ref base object memory
     * \return #EPS_ErrorType
     *
     * **************************************************************************************************
     *
     * \note
     *      This function is called after the base.pre method.
     *
     * \note
     *   The base.work function is called cyclic ever specified period.
     *
     * \note
     *   If the function is overwritten, additional error codes could be returned
     *
     */
    fnc_base_objCall_t work;


    /**
     * \brief object prototype method
     *
     * The post implementation of the class base is called after all base.work
     * routines where called.
     * This interface allows cyclic manipulation of variables after the application is finished.
     * Here writing buffers, transmitting bus packages, ect. cloud be performed.
     *
     * \param void*                              This pointer to the \ref base object memory
     * \return #EPS_ErrorType
     *
     * **************************************************************************************************
     *
     * \note
     *      This function is called after the base.work method.
     *
     * \note
     *   The base.post function is called cyclic ever specified period.
     *
     * \note
     *   If the function is overwritten, additional error codes could be returned
     *
     */
    fnc_base_objCall_t post;


    /**
     * \brief object prototype method
     *
     * The idle implementation of the class base is called after if there is
     * operation time left.
     * Within this implementation writing logs, comfort functions, ... could be performed.
     *
     * \param void*                              This pointer to the \ref base object memory
     * \return #EPS_ErrorType
     *
     * **************************************************************************************************
     *
     * \remarks
     *      This function is called if there is operation time left.
     *      The call period is not specified and the operation could be interrupted.
     *
     * \note
     *   Take care, the operation could be interrupted. Writing to real time variables
     *   could be dangerous.
     *
     */
    fnc_base_objCall_t idle;



} base_t;


/**************************************************************************************************
 *
 * F U N C T I O N S
 *
 *************************************************************************************************/


/**********************************************************************************************//**
 *
 * \brief implement of an base.init method
 *
 * This implementation initializes a base object.
 * To do so, nothin else than a pointer check is perforemd.
 *
 * \retval #EPS_E_OK                        everything fine, init is finished
 * \retval #EPS_E_NULLPTR                   null pointer exception, this is a fatal error, the operation has to be stooped
 *
 *
 *************************************************************************************************/
EPS_ErrorType base_init(base_t* const self);


/**********************************************************************************************//**
 *
 * \brief implement of an base.pre method
 *
 * In the implementation of the base class only a null
 * pointer check is performed.
 * For more functionality a derivation has to be created
 *
 * \retval #EPS_E_OK
 * \retval #EPS_E_NULLPTR
 *
 *
 * \note
 *   If the function is overwritten, additional error codes could be returned
 *
 *************************************************************************************************/
EPS_ErrorType base_pre(base_t* const self);


/**********************************************************************************************//**
 *
 * \brief implement of an base.work method
 *
 * In the implementation of the base class only a null
 * pointer check is performed.
 * For more functionality a derivation has to be created
 *
 * \retval #EPS_E_OK
 * \retval #EPS_E_NULLPTR
 *
 *
 * \note
 *   If the function is overwritten, additional error codes could be returned
 *
 *************************************************************************************************/
EPS_ErrorType base_work(base_t* const self);

/**********************************************************************************************//**
 *
 * \brief implement of an base.post method
 *
 * In the implementation of the base class only a null
 * pointer check is performed.
 * For more functionality a derivation has to be created
 *
 * \retval #EPS_E_OK
 * \retval #EPS_E_NULLPTR
 *
 *
 * \note
 *   If the function is overwritten, additional error codes could be returned
 *
 *************************************************************************************************/
EPS_ErrorType base_post(base_t* const self);


/**********************************************************************************************//**
 *
 * \brief implement of an base.idle method
 *
 * In the implementation of the base class only a null
 * pointer check is performed.
 * For more functionality a derivation has to be created
 *
 * \retval #EPS_E_OK
 * \retval #EPS_E_NULLPTR
 *
 *
 * \note
 *   If the function is overwritten, additional error codes could be returned
 *
 *************************************************************************************************/

EPS_ErrorType base_idle(base_t* const self);


#endif
