/*
 * EepromValveIslandInfo.c
 *
 *  Created on: Apr 16, 2025
 *      Author: tummalanr
 */


#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <stdarg.h>
#include <kernel/dpl/ClockP.h>
#include <inttypes.h>
#include <kernel/dpl/DebugP.h>
#include <kernel/dpl/TaskP.h>
#include <kernel/dpl/QueueP.h>
#include <kernel/dpl/EventP.h>
#include <kernel/dpl/SemaphoreP.h>
#include <drivers/spinlock.h>
#include <drivers/ipc_notify.h>

#include    "AppSharedMemory.h"
#include    "EepromAccess.h"
#include    "EepromAccessExtern.h"
#include    "ti_board_open_close.h"
#include    "SharedMemoryGlobal.h"
#include "InterfaceHeader.h"

extern uint8_t assignslots;
AppRET_T EepromTest(void);


static uint32_t
APP_aEepromAccessTaskStack_g[APP_EEPROMACCS_TASK_STACK_SIZE/sizeof(uint32_t)] __attribute__((aligned(32), section(".threadstack"))) = {0};

static TaskP_Object APP_EepromAccessTaskObj_g = { 0 };


volatile    uint32_t    eeprom_write_flag = 0u;
volatile    uint32_t    eeprom_read_flag = 0u;

uint32_t    CIP_IPAddress[2u]   = {0u};
uint32_t    MAINCore_IPAddress  = 0u;

uint8_t     MAINCORE_DEFAULT_MACADDRESS[6u] = {0x00u,0x11u,0x22u,0x33u,0x44u,0x55u};
uint8_t     CIP_INST1_DEFAULT_MACADDRESS[6u] = {0x11u,0x22u,0x33u,0x44u,0x55u,0x66u};
uint8_t     CIP_INST2_DEFAULT_MACADDRESS[6u] = {0x22u,0x33u,0x44u,0x55u,0x66u,0x77u};

uint16_t    MAINCORE_DEFAULT_PIN =   1111u;
uint64_t    MAINCORE_DEFAULT_PSWD =  12345678u;

// Read Semaphore for synch for EXPLICIT
SemaphoreP_Object gEepromAccessReqSynch;

uint32_t    cip_posterrors = 0u;

AppRET_T    App_EepromTemp_TaskInit(void)
{

    int32_t         status;
    int32_t taskErr = SystemP_SUCCESS;
    TaskP_Params    appeepromTaskParam = { 0 };
    AppRET_T        sts = 0u;


    // Req semaphore for synch  for Eeprom Access
    SemaphoreP_constructBinary(&gEepromAccessReqSynch, 0);
    Release_EepromAccess();

    //return AppRET_OK;

    sts = EepromTest();
    if(sts != AppRET_OK) {
        DebugP_log("[CIP] %s : CIP_EEPROM_ERROR!!!\r\n",__func__);
        cip_posterrors |= CIP_EEPROM_ERROR;
        return EepromTestError;
    }

    DebugP_log("[CIP] %s : CIP_EEPROM_OK!!!\r\n",__func__);

    status = EventP_construct(&gEepromAccessSynchEvent);
    DebugP_assert(SystemP_SUCCESS == status);

    //create SystemConfig WR task  For Writing SystemConfigs Data to SHM
    TaskP_Params_init (&appeepromTaskParam);

    appeepromTaskParam.name        = "eeprom_accesstask";
    appeepromTaskParam.stackSize   = sizeof(APP_aEepromAccessTaskStack_g);
    appeepromTaskParam.stack       = (uint8_t*)APP_aEepromAccessTaskStack_g;
    appeepromTaskParam.priority    = OSAL_TASK_Prio_10;
    appeepromTaskParam.taskMain    = (TaskP_FxnMain)APP_EepromAccessTask;
    appeepromTaskParam.args        = NULL;

    taskErr = TaskP_construct(&APP_EepromAccessTaskObj_g, &appeepromTaskParam);
    if (taskErr != SystemP_SUCCESS)
    {
      DebugP_log("[APP] ERROR: Failed to create task %s (%ld)\r\n",appeepromTaskParam.name, taskErr);
      TaskP_destruct(&APP_EepromAccessTaskObj_g);
      return EepromTaskCreateError;
    }

    return AppRET_OK;
}


/*!
 *  <!-- Description: -->
 *
 *  \brief
 *          This Task is used for Eeprom Read Write Access
 *
 *  <!-- Parameters and return values: -->
 *  \param[in]  pArgs_p         -    Not Used.
 *
 *  \return     None.
 */
void APP_EepromAccessTask(void* pArgs_p)
{
    AppRET_T    sts = 0u;
    int32_t     status;
    uint32_t    eventBits;


    (void)sts;
    status = EventP_clearBits(&gEepromAccessSynchEvent, EEPROM_WRITE_EVENT_BIT | EEPROM_READ_EVENT_BIT | TEMPERATURE_READ_EVENT_BIT);

    for(;;)
    {
        status = EventP_waitBits(&gEepromAccessSynchEvent, EEPROM_WRITE_EVENT_BIT | EEPROM_READ_EVENT_BIT | TEMPERATURE_READ_EVENT_BIT,
                                 0u, 0u, SystemP_WAIT_FOREVER, &eventBits);
        if(status != SystemP_SUCCESS ) {
            continue;
        }


        if(Get_EepromAccess() != AppRET_OK) {
                       continue;
        }

        if( eventBits & EEPROM_WRITE_EVENT_BIT)
        {
                //DebugP_log("%s EEPROM_WRITE_EVENT_BIT Triggered  eeprom_write_flag[%#x]\r\n",__func__,eeprom_write_flag);

                if(eeprom_write_flag & EEPROM_MODULEDISCOVERY) {

                    eeprom_write_flag &= ~EEPROM_MODULEDISCOVERY;
                }

                if(eeprom_write_flag == 0u) {
                    status = EventP_clearBits(&gEepromAccessSynchEvent, EEPROM_WRITE_EVENT_BIT);
                }

        }
        if( eventBits & EEPROM_READ_EVENT_BIT)
        {
            if(eeprom_read_flag == 0u) {
                status = EventP_clearBits(&gEepromAccessSynchEvent, EEPROM_READ_EVENT_BIT);
            }
        }

        if( eventBits & TEMPERATURE_READ_EVENT_BIT) {

            status = EventP_clearBits(&gEepromAccessSynchEvent, TEMPERATURE_READ_EVENT_BIT);
        }

        Release_EepromAccess();

    }//for(;;)

}

AppRET_T    Get_EepromAccess(void)
{
    int32_t     sempsts = SystemP_FAILURE;
    uint32_t sempto = ClockP_usecToTicks(50000u);       //50msec

    sempsts = SemaphoreP_pend(&gEepromAccessReqSynch, sempto);
    if( (sempsts == SystemP_FAILURE) || (sempsts == SystemP_TIMEOUT) )
    {//timeout
        //DebugP_log("%s  sempsts[%d] [%" PRId64 " ms]\r\n",__func__,sempsts, (ClockP_getTimeUsec()/1000u));
        Release_EepromAccess();
       return EepromWriteError;
    }
    return AppRET_OK;
}

AppRET_T    Release_EepromAccess(void)
{
    SemaphoreP_post(&gEepromAccessReqSynch);
    return AppRET_OK;
}

AppRET_T EepromTest(void)
{
    uint32_t    address  = EEPROMTESTADDR;
    uint8_t     databuf[10u] = {0u};
    uint8_t     wrdatabuf[10u] = {0x11u,0x22u,0x33u,0x44u,0x55u,0x66u};
    uint8_t     len = 6u;
    int32_t     retVal;


    if(Get_EepromAccess() != AppRET_OK) {
          return EepromTestError;
    }

    //uint64_t started = (ClockP_getTimeUsec()/1000u);
    //DebugP_log("%s  Write @ %d Bytes @ [%#x]  [%" PRId64 " ms]\r\n",__func__,len,address, started);
    //write new discovery data
    retVal = EEPROM_write(gEepromHandle[CONFIG_EEPROM0], address, &wrdatabuf[0u], len);
    if(retVal != SystemP_SUCCESS)
    {
        DebugP_log("%s  Write Bytes failure @ [%#x]  [%" PRId64 " ms]\r\n",__func__,address, (ClockP_getTimeUsec()/1000u));
        Release_EepromAccess();
        return EepromWriteError;
    }
    retVal = EEPROM_read(gEepromHandle[CONFIG_EEPROM0], address, &databuf[0], len);
    if(retVal != SystemP_SUCCESS)
    {
      DebugP_log("%s  Read Bytes failure @ [%#x]  [%" PRId64 " ms]\r\n",__func__,address, (ClockP_getTimeUsec()/1000u));
      Release_EepromAccess();
      return EepromReadError;
    }
    Release_EepromAccess();

    //for(uint8_t i = 0u; i< len; i++)
    //{
      //DebugP_log("%s [%d]  [%#x] [%#x] \r\n",__func__,(i + 1u),address,databuf[i]);
    //}

    if(memcmp(&databuf[0],&wrdatabuf[0],6u) != 0u)
    {
        return EepromTestError;
    }

    return AppRET_OK;
}
