/*
 * tmos.c
 *
 *  Created on: Feb 29, 2024
 *      Author: Administrator
 */
 #include "include.h"
#include "typedef.h"
#include "tmos.h"
#include "string.h"
#include "driver_tmr.h"

#define TASK_ID_MAX 10
#define TASK_EVENT_MAX  16


static uint8_t tmos_num = 0;

typedef struct{
    tmosEvents event;
    tmosTimer timer[TASK_EVENT_MAX];
    tmosTimer time_stamp[TASK_EVENT_MAX];
    pTaskEventHandlerFn TaskEventHandlerFn;
}ST_TASK;

static ST_TASK tmosTask[TASK_ID_MAX];
static tmosTimer time_stamp = 0;



static tmosTimer toms_tick=0;

AT(.com_text.isr)
void timer3_isq(void)
{
    if (tmr_get_flag(TMR3, TMR_IT_UPDATE) != RESET) {
        tmr_clear_flag(TMR3, TMR_IT_UPDATE);
         toms_tick++;

    }
}

void timer3_650us_init(void)
{
    tmr_base_init_typedef tmr_base_init_struct;
    clk_gate1_cmd(CLK_GATE1_TMR3, CLK_EN);

    tmr_base_init_struct.clock_source = TMR_COUNTER_RISING;
    tmr_base_init_struct.counter_source = TMR_INC_SOURCE;       // 1MHz
    tmr_base_init_struct.prescale = 1 - 1;                   // 1KHz
    tmr_base_init_struct.period = 650 - 1;                      // 5Hz
    tmr_base_init(TMR3, &tmr_base_init_struct);

    tmr_pic_config(TMR3, timer3_isq, 0, TMR_IT_UPDATE, ENABLE);

    tmr_cmd(TMR3, ENABLE);


    gpio_init_typedef gpio_init_structure;
    gpio_init_structure.gpio_pin = GPIO_PIN_4;
    gpio_init_structure.gpio_dir = GPIO_DIR_OUTPUT;
    gpio_init_structure.gpio_fen = GPIO_FEN_GPIO;
    gpio_init_structure.gpio_mode = GPIO_MODE_DIGITAL;
    gpio_init_structure.gpio_drv = GPIO_DRV_6MA;
    gpio_init(GPIOA_REG, &gpio_init_structure);
}


bStatus_t tmos_init()
{
    tmos_num = 0;

    memset((void*)tmosTask, 0, sizeof(tmosTask));

    toms_tick = 0;
    time_stamp = 0;

    timer3_650us_init();
    return 0;
}



bStatus_t tmos_set_event( tmosTaskID taskID, tmosEvents event )
{
    tmosTask[taskID].event |= event;
    return 0;
}

bStatus_t tmos_start_task( tmosTaskID taskID, tmosEvents event, tmosTimer time  )
{
    uint8_t i;

    tmosTask[taskID].event |= event;

    for(i=0; i<TASK_EVENT_MAX; i++)
    {
       if((event >> i) & 0x01)
       {
           tmosTask[taskID].timer[i] = time ;
           break;
       }
    }
    return 0;
}

bStatus_t tmos_stop_task( tmosTaskID taskID, tmosEvents event )
{
    uint8_t i;

    tmosTask[taskID].event &= ~event;

    for(i=0; i<TASK_EVENT_MAX; i++)
    {
        if((event >> i) & 0x01)
        {
            tmosTask[taskID].timer[i] = 0;
            break;
        }
    }
    return 0;
}

void TMOS_SystemProcess( void )
{
    uint8_t i,j,tick = 0;
    tmosEvents event;

    if(toms_tick==time_stamp)
        return;

    tick = toms_tick - time_stamp;
    time_stamp = toms_tick;


    for(i = 0; i<tmos_num; i++)
    {
        if(tmosTask[i].event == 0)
        {
            continue;
        }
        else
        {
            //PRINT("task_id=%d\n", i);
            for(j=0; j<TASK_EVENT_MAX; j++)
            {
                event = 1L<<j;

                if(tmosTask[i].event & event)
                {
                    //PRINT("task_event=%d\n", j);
                    if(tmosTask[i].timer[j] > tick)
                    {
                        //PRINT("timer=%d\n", tmosTask[i].timer[j]);
                        tmosTask[i].timer[j]-=tick;
                    }
                    else if(tmosTask[i].timer[j] <= tick)
                    {
                        //PRINT("timer=%d\n", tmosTask[i].timer[j]);

                        tmosTask[i].timer[j] = 0;

                        tmosTask[i].event &= ~event;

                        tmosTask[i].TaskEventHandlerFn((tmosTaskID)i, event);
                    }
                }
            }
        }
    }
}

tmosTaskID TMOS_ProcessEventRegister( pTaskEventHandlerFn eventCb )
{
    if(tmos_num >= TASK_ID_MAX)
    {
        return INVALID_TASK_ID;
    }
    else
    {
        tmosTask[tmos_num++].TaskEventHandlerFn = eventCb;
    }
    return tmos_num - 1;
}
