/*
 * DataSyncIOTasks.c
 *
 *  Created on: Nov 15, 2025
 *      Author: tummalanr
 */


#include <stdio.h>
#include <string.h>
#include <inttypes.h>
#include <drivers/spinlock.h>
#include <drivers/ipc_notify.h>
#include "FreeRTOS.h"
#include "event_groups.h"
#include "queue.h"

#include "AppGlobal.h"
#include "AppExterns.h"
#include "BoardInitExtern.h"
#include "CIPCoreDataSynchGlobal.h"
#include "ShmDataSyncExterns.h"
#include "CIPCoreExterns.h"
#include "ValveModulesExterns.h"
#include "MCanExterns.h"
#include "MainCoreExterns.h"
#include "IOModuleStructs.h"
#include "IOModulesExtern.h"



/*!
 *  <!-- Description: -->
 *
 *  \brief
 *
 *   IO Modules Acquire Shared Memory Lock for Processing IPC Cyclic Messages/Data
 *
 *  <!-- Parameters and return values: -->
 *  \param[in] :None
 *  \return    :
 *              AppRET_T  : AppRET_OK on Success or Error
 */
static AppRET_T io_sharemem_cycliclock(void)
{
    int32_t     status;
    int32_t     sempstatus;
    uint32_t    timeout = SPINLOCK_GET_TIMEOUT;

    /* Take local mutex to protect against multi-thread from same core */
    sempstatus = SemaphoreP_pend(&Cyclic_IOModules_mutexObj, 10u);
    if(sempstatus != SystemP_SUCCESS) {

       return AppGetSHMLockErr;
    }

    /* Spin till lock is acquired or timeout.*/
    for(;;)
    {
      status = Spinlock_lock(spinlockBaseAddr, SPINLOCKNO_CYCLIC_IOMODULES);
      if(status == SPINLOCK_LOCK_STATUS_FREE) {
          break;  /* Free and taken */
      }

      timeout--;
      if(timeout == 0) {
              break;
      }

      //vTaskDelay( 1u );
      __asm__ volatile ("nop"); /* Prevent compiler from optimizing away the loop.*/
    }
    if(timeout == 0) {
      return AppGetSHMLockTimeOutErr;
    }

    return AppRET_OK;
}

/*!
 *  <!-- Description: -->
 *
 *  \brief
 *
 *   IO Modules Release Cyclic Shared Memory Lock
 *
 *  <!-- Parameters and return values: -->
 *  \param[in] : None
 *  \return    : None
 */
static void io_sharemem_cyclicunlock(void)
{
    /* Free the aquired lock and release local mutex.*/
    Spinlock_unlock(spinlockBaseAddr, SPINLOCKNO_CYCLIC_IOMODULES);
    SemaphoreP_post(&Cyclic_IOModules_mutexObj);

    return;
}

/*!
 *  <!-- Description: -->
 *
 *  \brief
 *
 *   IO Modules Data Sync Req/Resp Task From CIP Core
 *
 *  <!-- Parameters and return values: -->
 *  \param[in] : * pArgs_p  Not Used
 *  \return    : None
 */
void APP_IOModulesCyclicTask(void* pArgs_p)
{
        uint8_t     updatetomaincore = 0u;
        //uint8_t instanceno = 0;
        //uint8_t chnlno = 0;
        //uint8_t brdtype = 0;
        AppRET_T sts = 0;
        EventBits_t uxBits;
        const TickType_t xTicksToWait = portMAX_DELAY;  // Delay_Ms_Ticks(5000u);


        /* wait for a resource to be available Wait for lss to complete*/
        for(;;)
        {
            /* Wait a maximum of 100ms for either bit 0 or bit 1 to be set within the event group. Clear the bits before exiting.*/
            uxBits = xEventGroupWaitBits(
                                        xAppStatusEventGroup,               /* The event group being tested. */
                                        (const EventBits_t)(AppStsEvntGrpLSSComplete_BIT |
                                        AppStsEvntGrpCIPSyncomplete_BIT |
                                        AppStsEvntGrpSysConfigUpd_BIT),      /* The bits within the event group to wait for. */
                                        pdFALSE,                            /* BIT_0 & BIT_4 should be cleared before returning. */
                                        pdTRUE,                             /*  wait for all bits */
                                        portMAX_DELAY );                    /* Wait a maximum of 100ms for either bit to be set. */

            //if( (uxBits & 0x07u) ==  (AppStsEvntGrpLSSComplete_BIT | AppStsEvntGrpCIPSyncomplete_BIT | AppStsEvntGrpSysConfigUpd_BIT) )
            if(uxBits != 0x0u) {
                break;
            }
        }

            BaseType_t clrsts =  xQueueReset( io_shmdataupdwrqueue );
            (void)clrsts;

            xEventGroupClearBits(  xCyclicEventGroup_IOModules,  (const EventBits_t)(CIPCyclicEventGrp_InputSts_BIT
                                                                 | CIPCyclicEventGrp_DOPSts_BIT | CIPCyclicEventGrp_AOValSts_BIT));

        for(;;)
        {
            /* Wait a maximum of 100ms for either bit 0 or bit 1 to be set within the event group. Clear the bits before exiting.*/
            uxBits = xEventGroupWaitBits(
                                xCyclicEventGroup_IOModules,                            /* The event group being tested. */
                                (const EventBits_t)(CIPCyclicEventGrp_InputSts_BIT |
                                CIPCyclicEventGrp_DOPSts_BIT   |
                                CIPCyclicEventGrp_AOValSts_BIT),                        /* The bits within the event group to wait for.*/
                                pdFALSE,                                                /* BIT_0 & BIT_4 should be cleared before returning. */
                                pdFALSE,                                                /* Don't wait for both bits, either bit will do. */
                                xTicksToWait );                                         /* Wait a maximum of 100ms for either bit to be set. */

            #ifdef Debug_Verbose2
                uint64_t    start = (ClockP_getTimeUsec()/1000u);
            #endif

                updatetomaincore = 0u;
                /*Cyclic Input Data received from Backplane or from DS send to CIP any one only is assumed will come*/
                if( ( uxBits & CIPCyclicEventGrp_InputSts_BIT ) != 0 )
                {
                    #ifdef Debug_Verbose2
                        DebugP_log("[[CAN CORE] %s if( ( uxBits &  CIPCyclicEventGrp_InputSts_BIT ) [%" PRId64 " ms]\r\n",__func__,(ClockP_getTimeUsec()/1000u));
                    #endif

                    /*Get data from queue and write to SHM Process IO data as per structure and send ipc notify to CIP CORE*/
                    UBaseType_t msgcnt = uxQueueMessagesWaiting(io_shmdataupdwrqueue);
                    if(msgcnt != 0u)
                    {
                        sts = io_sharemem_cycliclock();
                        if(sts == AppRET_OK)
                        {
                            CyclicData_SHMUpdate_Info   pxodDataMessage = {0};
                            for(uint8_t cntr = 0; cntr < (uint8_t)msgcnt; cntr++)
                            {
                                if(xQueueReceive(io_shmdataupdwrqueue, &(pxodDataMessage), (TickType_t)MSGQUEUE_RECV_TO) )
                                {
                                    //uint32_t msgValue = IOMODULEMSG_NOTIFY_ID;
                                    AppRET_T changedsts = APPCyclicDataNotChanged;

                                    changedsts = Process_IO_CyclicInputSts_SHM(&pxodDataMessage);
                                    //(void)changedsts;
                                    //io_sharemem_cyclicunlock();
                                    if(changedsts == APPCyclicDataChanged) {
                                        updatetomaincore=1u;
                                    }

                                   /* if(changedsts == APPCyclicDataChanged)
                                    {
                                        #ifdef Debug_Verbose2
                                             DebugP_log("APPCyclicDataChanged [%" PRId64 " ms] paramtype[%d]\r\n",(ClockP_getTimeUsec()/1000u),pxodDataMessage.paramtype);
                                         #endif

                                        if( pxodDataMessage.paramtype == IPC_DI_STS_DATA)
                                            msgValue |= IOCYCLIC_DISTS_NOTIFY_ID;
                                        else if( pxodDataMessage.paramtype == IPC_AIVAL_STS_DATA )
                                            msgValue |= IOCYCLIC_AIVALUE_NOTIFY_ID;
                                        else if( pxodDataMessage.paramtype == IPC_AICNT_STS_DATA )
                                            msgValue |= IOCYCLIC_AICOUNT_NOTIFY_ID;
                                        else if( pxodDataMessage.paramtype == IPC_IOMODULE_ERR_DATA )
                                            msgValue |= IOCYCLIC_IOERRSTS_NOTIFY_ID;

                                        msgValue |= pxodDataMessage.posno;
                                        if(CIP_Synch_Done)
                                            IpcNotify_sendMsg(CSL_CORE_ID_R5FSS0_0, IOModules_IPC_ClientId, msgValue, 1);  //notify the CIP core response is ready

                                    }//if(changedsts == APPCyclicDataChanged)*/
                                }//if(xQueueReceive(io_shmdataupdwrqueue, &(pxodDataMessage), (TickType_t)MSGQUEUE_RECV_TO) )

                                if(cntr > 6) {
                                    break;          //safer to give access to other tasks
                                }
                            }//for(uint8_t cntr = 0; cntr < (uint8_t)msgcnt; cntr++)
                            io_sharemem_cyclicunlock();
                        }//if(sts == AppRET_OK)

                    }//if(uxQueueMessagesWaiting(io_shmdataupdwrqueue) != 0u)
                    //else
                    if(uxQueueMessagesWaiting(io_shmdataupdwrqueue) == 0u) {
                        xEventGroupClearBits(xCyclicEventGroup_IOModules, CIPCyclicEventGrp_InputSts_BIT);
                    }

                }//if( ( uxBits & CIPCyclicEventGrp_InputSts_BIT ) != 0 )

            //Cyclic Output Data received from CIP send to Backplane or from DS any one only is assumed will come
            if( ( uxBits &  CIPCyclicEventGrp_DOPSts_BIT ) != 0 )
            {
                xEventGroupClearBits(xCyclicEventGroup_IOModules, CIPCyclicEventGrp_DOPSts_BIT);

                #ifdef Debug_Verbose2
                    DebugP_log("[[CAN CORE] %s if( ( uxBits &  CIPCyclicEventGrp_DOPSts_BIT ) [%" PRId64 " ms]\r\n",__func__,(ClockP_getTimeUsec()/1000u));
                #endif

                //sts = io_sharemem_cycliclock();
                //if(sts == AppRET_OK)
                {
                    Process_DO_CyclicOutputSts();

                    //io_sharemem_cyclicunlock();
                }//if(sts == 0)
            }//if( ( uxBits & CIPCyclicEventGrp_DOPSts_BIT ) != 0 )
            else if( ( uxBits &  CIPCyclicEventGrp_AOValSts_BIT) != 0 )
            {
                xEventGroupClearBits(xCyclicEventGroup_IOModules, CIPCyclicEventGrp_AOValSts_BIT);

                #ifdef Debug_Verbose2
                    DebugP_log("[[CAN CORE] %s if( ( uxBits &  CIPCyclicEventGrp_AOValSts_BIT ) [%" PRId64 " ms]\r\n",__func__,(ClockP_getTimeUsec()/1000u));
                #endif

                //sts = io_sharemem_cycliclock();
                //if(sts == AppRET_OK)
                {
                    Process_AO_CyclicOutputVal();

                    //io_sharemem_cyclicunlock();
                }//if(sts == 0)
            }//else if( ( uxBits &  CIPCyclicEventGrp_AOValSts_BIT) != 0 )



               if( updatetomaincore )
               {
                    #ifdef Debug_Verbose2
                     DebugP_log("[[CAN] %s  end [%" PRId64 " ms]uxBits[%#x] MainCore_Synch_Done[%d] updatetomaincore[%d]\r\n",__func__,(ClockP_getTimeUsec()/1000u),uxBits,MainCore_Synch_Done,updatetomaincore);
                    #endif
                   //Update IO Modules Cyclic Info  to Main Core
                   if(MainCore_Synch_Done) {
                       xEventGroupSetBits(xAppMainCoreShmAccessEventGroup, MainCoreUpdtIOCyclic_WRBIT);
                   }
               }
            taskYIELD();
        }//for(;;)
}


/*!
 *  <!-- Description: -->
 *
 *  \brief
 *
 *   IO Modules Acquire Shared Memory Lock for Processing IPC Acyclic Messages/Data
 *
 *  <!-- Parameters and return values: -->
 *  \param[in] :None
 *  \return    :
 *              AppRET_T  : AppRET_OK on Success or Error
 */
AppRET_T io_sharemem_acycliclock(void)
{
    int32_t  status;
    int32_t  sempstatus;
    uint16_t  timeout = SPINLOCK_GET_TIMEOUT;

    /* Take local mutex to protect against multi-thread from same core */
    sempstatus = SemaphoreP_pend(&ACyclic_IOModules_mutexObj, 10u);       //SystemP_WAIT_FOREVER   10000
    if(sempstatus != SystemP_SUCCESS) {
               return AppGetSHMLockErr;
    }

    /* Spin till lock is acquired or timeout.*/
    while(1u)
    {
      status = Spinlock_lock(spinlockBaseAddr, SPINLOCKNO_ACYCLIC_IOMODULES);
      if(status == SPINLOCK_LOCK_STATUS_FREE) {
          break;  /* Free and taken */
      }

      timeout--;
      if(timeout == 0u) {
              break;
      }

      //vTaskDelay( 1u );
      __asm__ volatile ("nop"); /* Prevent compiler from optimizing away the loop.*/
    }
    if(timeout == 0u) {
      return AppGetSHMLockTimeOutErr;
    }

    return AppRET_OK;
}

/*!
 *  <!-- Description: -->
 *
 *  \brief
 *
 *   IO Modules Release ACyclic Shared Memory Lock
 *
 *  <!-- Parameters and return values: -->
 *  \param[in] : None
 *  \return    : None
 */
void io_sharemem_acyclicunlock(void)
{
    // Free the aquired lock and release local mutex
    Spinlock_unlock(spinlockBaseAddr, SPINLOCKNO_ACYCLIC_IOMODULES);
    SemaphoreP_post(&ACyclic_IOModules_mutexObj);

    return;
}



/*!
 *  <!-- Description: -->
 *
 *  \brief
 *          This Task is used for Getting IO Modules Acyclic Data from BackPlane
 *          -  Getting the IO Modules   STATIC_CONSTANT_DATA , STATIC_CONFIG_DATA type Parameters Periodically untill available Status marked.
 *          -  Getting the IO Modules   Data as per Request from CIP Core. STATIC_VARIABLE_DATA Handles Request / Response events
 *
 *  <!-- Parameters and return values: -->
 *  \param[in]  pArgs_p         -    Not Used.
 *
 *  \return     None.
 */
void APP_IOModulesACyclicTask(void* pArgs_p)
{
    //uint32_t    msgValue = 0;
    AppRET_T sts = 0;
    EventBits_t uxBits;


    /* wait for a resource to be available Wait for lss to complete.*/
    for(;;)
    {
        /* Wait a maximum of 100ms for either bit 0 or bit 1 to be set within the event group. Clear the bits before exiting.*/
        uxBits = xEventGroupWaitBits(
                                    xAppStatusEventGroup,                                           /* The event group being tested. */
                                    (const EventBits_t)(AppStsEvntGrpLSSComplete_BIT |
                                            AppStsEvntGrpSysConfigUpd_BIT),                         /* The bits within the event group to wait for. */
                                    pdFALSE,                                                        /* BIT_0 & BIT_4 should be cleared before returning. */
                                    pdTRUE,                                                         /*  wait for all bits */
                                    portMAX_DELAY );                                                /* Wait a maximum of 100ms for either bit to be set. */

        //if(  (uxBits & 0x05u)  == ( AppStsEvntGrpLSSComplete_BIT |  AppStsEvntGrpSysConfigUpd_BIT) )
        if(  uxBits != 0x00u) {
                break;
        }
    }

    //vTaskDelay( 100u );
    xEventGroupClearBits(xACyclicEventGroup_IOModules, (const EventBits_t)(CIPACyclicEventGrp_WRReq_BIT  | CIPACyclicEventGrp_RDReq_BIT | CIPACyclicEventGrp_Resp_BIT) );

    for(;;)
    {
        /* Wait a maximum of 100ms for either bit 0 or bit 1 to be set within the event group. Clear the bits before exiting.*/
        uxBits = xEventGroupWaitBits(
                            xACyclicEventGroup_IOModules,                                                               /* The event group being tested. */
                            (const EventBits_t)(CIPACyclicEventGrp_WRReq_BIT  | CIPACyclicEventGrp_RDReq_BIT|
                                    CIPACyclicEventGrp_Resp_BIT),                                                       /* The bits within the event group to wait for.  |*/
                            pdFALSE,                                                                                    /* BIT_0 & BIT_4 should be cleared before returning. */
                            pdFALSE,                                                                                    /* Don't wait for both bits, either bit will do. */
                            5000u );                                                                                    /* Wait a maximum of 100ms for either bit to be set. */


            //ACyclic Wr Req Data received from CIP send to Backplane
            if( ( uxBits & CIPACyclicEventGrp_WRReq_BIT ) != 0 )
            {
                xEventGroupClearBits(xACyclicEventGroup_IOModules, CIPACyclicEventGrp_WRReq_BIT);

                ioacyclic_client_reqresp     ioacyclicreq = {0u};

                //sts = io_sharemem_acycliclock();
                //if(sts == AppRET_OK)
                {
                    ioacyclicreq = IOAcyclic_WRRequest;
                    ioacyclicreq.reqclient = CLIENT_CIP_IO;

                    //io_sharemem_acyclicunlock();
                }//if(sts == AppRET_OK)

                if( (ioacyclicreq.BoardId != IO_NONE) && (ioacyclicreq.rwmode == DATA_WR) )
                {
                    IOAcyclicWRReqProcess = 1u;

                    AppRET_T sts1 = Process_IO_ACyclic_req(&ioacyclicreq);

                    //update req response status to SHM send  notify to CIP
                    if(sts1 == APPAcyclicDataChanged)
                    {
                        sts = io_sharemem_acycliclock();
                        if(sts == AppRET_OK)
                        {
                            ioacyclic_client_reqresp     ioacyclicresp;

                            ioacyclicresp = ioacyclicreq;
                            ioacyclicresp.respsts = sts1;

                            IOAcyclic_WRResponse = ioacyclicresp;

                            IOAcyclic_WRRequest.BoardId = IO_NONE;      //Write Complete so clear Write Request used in CIP

                            io_sharemem_acyclicunlock();

                            //Add later the resp to CIP
                            //msgValue = 0u;
                            //msgValue |= IOACYCLIC_NOTIFY_ID | ioacyclicresp.PosId;     //lATER ADD SPECIFIC TYPES
                            //IpcNotify_sendMsg(CSL_CORE_ID_R5FSS0_0, IOModules_IPC_ClientId, msgValue, 1);  //notify the CIP core response is ready

                        }//if(sts == AppRET_OK)

                        #ifdef Debug_Verbose2
                           DebugP_log("[CAN] %s- ioacyclicreq.PosId [%d] iomodulediscoverycnt[%d]\r\n",__func__,ioacyclicreq.PosId,iomodulediscoverycnt);
                       #endif

                    }//if(sts1 == AppRET_OK)

                    IOAcyclicWRReqProcess = 0u;

                }//if( (ioacyclicreq.BoardId != IO_NONE) && (ioacyclicreq.rwmode == DATA_WR) )

                #ifdef Debug_Verbose2
                    DebugP_log("[CAN CORE] ipccbstart [%" PRId64 " ms]  ipccbend [%" PRId64 " ms] start [%" PRId64 " ms]  end [%" PRId64 " ms]\r\n",ipccbstart,ipccbend,started,(ClockP_getTimeUsec()/1000u));
                #endif

        }//if( ( uxBits & CIPACyclicEventGrp_WRReq_BIT ) != 0 )//ACyclic Wr Req Data received from CIP send to Backplane

        if( ( uxBits & CIPACyclicEventGrp_RDReq_BIT ) != 0 )
        {
            xEventGroupClearBits(xACyclicEventGroup_IOModules, CIPACyclicEventGrp_RDReq_BIT);

            #ifdef Debug_Verbose2
                DebugP_log("[[CAN CORE] %s- CIPACyclicEventGrp_RDReq_BIT [%" PRId64 " ms]\r\n",__func__,(ClockP_getTimeUsec()/1000u));
                uint64_t    started = (ClockP_getTimeUsec()/1000u);
            #endif

            ioacyclic_client_reqresp     ioacyclicreq;

            //sts = io_sharemem_acycliclock();
            //if(sts == AppRET_OK)
            {
                ioacyclicreq = IOAcyclic_RDRequest;
                ioacyclicreq.reqclient = CLIENT_CIP_IO;

                //io_sharemem_acyclicunlock();
            }//if(sts == AppRET_OK)

            #ifdef Debug_Verbose2
                DebugP_log("[[CAN CORE] %s- IOAcyclicRDReqProcess[%d] ioacyclicreq.BoardId[%#x] [%" PRId64 " ms]\r\n",__func__,IOAcyclicRDReqProcess,ioacyclicreq.BoardId,(ClockP_getTimeUsec()/1000u));
            #endif

            if( (ioacyclicreq.BoardId != IO_NONE) && (ioacyclicreq.rwmode == DATA_RD) )
            {
                IOAcyclicRDReqProcess = 1u;

                    AppRET_T sts1 = Process_IO_ACyclic_req(&ioacyclicreq);

                    #ifdef Debug_Verbose2
                        DebugP_log("[[CAN CORE] %s- After Process_IO_ACyclic_req sts1[%#x] [%" PRId64 " ms]\r\n",__func__,sts1,(ClockP_getTimeUsec()/1000u));
                    #endif

                    sts = io_sharemem_acycliclock();
                    if(sts == AppRET_OK)
                    {
                        //update req response status to SHM send  notify to CIP
                        if(sts1 == APPAcyclicDataChanged)
                        {
    //                        sts = io_sharemem_acycliclock();
    //                        if(sts == AppRET_OK)
    //                        {
                                ioacyclic_client_reqresp     ioacyclicresp;

                                ioacyclicresp = ioacyclicreq;
                                ioacyclicresp.respsts = 0;

                                IOAcyclic_RDResponse = ioacyclicresp;

                                IOAcyclic_RDRequest.BoardId = IO_NONE;      //Read Complete so clear Read Request used in CIP
                                //io_sharemem_acyclicunlock();
                                /*
                                if( ioacyclicreq.PosId && (ioacyclicreq.PosId <= iomodulediscoverycnt) )
                                {
                                    uint8_t boardtype = iomodulediscoveryinfo[ioacyclicreq.PosId - 1u].BoardId;
                                    msgValue = 0u;

                                    switch(boardtype)
                                    {
                                        case    DI_M8:
                                        case    DI_M12:
                                                        msgValue = IOACYCLIC_DI_NOTIFY_ID;
                                                        break;
                                        case    DIO_M8:
                                        case    DIO_M12:
                                                        msgValue = IOACYCLIC_DIO_NOTIFY_ID;
                                                        break;
                                        case    DO_M8:
                                        case    DO_M12:
                                                        msgValue = IOACYCLIC_DO_NOTIFY_ID;
                                                        break;
                                        case    AI_M12:
                                                        msgValue = IOACYCLIC_AI_NOTIFY_ID;
                                                        break;
                                        case    AO_M12:
                                                        msgValue = IOACYCLIC_AO_NOTIFY_ID;
                                                        break;
                                        case    AIO_M12:
                                                        msgValue = IOACYCLIC_AIO_NOTIFY_ID;
                                                        break;
                                        default:
                                                        break;
                                    }//switch(boardtype)

                                    if( msgValue != 0u)
                                    {
                                        msgValue |= ioacyclicresp.PosId;
                                        if(CIP_Synch_Done)
                                        {
                                            IpcNotify_sendMsg(CSL_CORE_ID_R5FSS0_0, IOModules_IPC_ClientId, msgValue, 1);  //notify the CIP core response is ready
                                        }
                                       #ifdef Debug_Verbose2
                                           DebugP_log("[CAN] %s- Acyclic RDreq  msgValue [%#x] acyclic_rdstart [%" PRId64 "] [%" PRId64 " ms] Dur [%" PRId64 " ms]\r\n",__func__,msgValue,acyclic_rdstart,(ClockP_getTimeUsec()/1000u),(ClockP_getTimeUsec()/1000u) - acyclic_rdstart);
                                       #endif
                                    }
                                }*/
                            //}//if(sts == AppRET_OK)
                        }//if(sts1 == APPAcyclicDataChanged)
                        else {
                            IOAcyclic_RDRequest.respsts = 1u;

                            IOAcyclic_RDRequest.BoardId = IO_NONE;      //Read Complete so clear Read Request used in CIP
                        }
                        io_sharemem_acyclicunlock();
                    }//if(sts == AppRET_OK)
                    IOAcyclicRDReqProcess = 0u;

            }//if( (ioacyclicreq.BoardId != IO_NONE) && (ioacyclicreq.rwmode == DATA_RD) )

            #ifdef Debug_Verbose2
                DebugP_log("[CAN CORE] ipccbstart [%" PRId64 " ms]  ipccbend [%" PRId64 " ms] start [%" PRId64 " ms]  end [%" PRId64 " ms]\r\n",ipccbstart,ipccbend,started,(ClockP_getTimeUsec()/1000u));
            #endif

        taskYIELD();

    }//if( ( uxBits & CIPACyclicEventGrp_RDReq_BIT ) != 0 )

        /*else if( ( uxBits & CIPACyclicEvntGrp_PrmUpdate_BIT ) != 0 )
        {
            xEventGroupClearBits(xACyclicEventGroup_IOModules, CIPACyclicEvntGrp_PrmUpdate_BIT);

            #ifdef Debug_Verbose2
                //uint64_t    scanstarted = (ClockP_getTimeUsec()/1000);
                DebugP_log("IO Instance Acyclic Scan started [%" PRId64 "]ms\r\n",(ClockP_getTimeUsec()/1000));
            #endif

            uint8_t boardtype = IO_NONE;
            for(uint8_t ioinstno = 0; ioinstno < IO_INSTANCE_MAX; ioinstno++)
            {
                //get Board Type of instance  and get all service parameters and update SHM and parameter avail status

                boardtype = iomodulediscoveryinfo[ioinstno].BoardId;
                if(boardtype == IO_NONE)
                {
                    break;
                }

                msgValue = 0u;
                switch(boardtype)
                {
                    case    DI_M8:
                    case    DI_M12:
                                    if( Process_DI_AcyclicData(ioinstno, DI_XX) == APPAcyclicDataChanged)
                                    {
                                        msgValue = IOACYCLIC_DI_NOTIFY_ID;
                                    }
                                    break;
                    case    DIO_M8:
                    case    DIO_M12:
                                    if( Process_DIO_AcyclicData(ioinstno) == APPAcyclicDataChanged)
                                    {
                                        msgValue = IOACYCLIC_DIO_NOTIFY_ID;
                                    }
                                    break;
                    case    DO_M8:
                    case    DO_M12:
                                    if(Process_DO_AcyclicData(ioinstno, DO_XX) == APPAcyclicDataChanged)
                                    {
                                        msgValue = IOACYCLIC_DO_NOTIFY_ID;
                                    }
                                    break;
                    case    AI_M12:
                                    if(Process_AI_AcyclicData(ioinstno, AI_XX) == APPAcyclicDataChanged)
                                    {
                                        msgValue = IOACYCLIC_AI_NOTIFY_ID;
                                    }
                                    break;
                    case    AO_M12:
                                    if(Process_AO_AcyclicData(ioinstno, AO_XX) == APPAcyclicDataChanged)
                                    {
                                        msgValue = IOACYCLIC_AO_NOTIFY_ID;
                                    }
                                    break;
                    case    AIO_M12:
                                    if(Process_AIO_AcyclicData(ioinstno) == APPAcyclicDataChanged)
                                    {
                                        msgValue = IOACYCLIC_AIO_NOTIFY_ID;
                                    }
                                    break;
                    default:
                                    break;
                }//switch(boardtype)

                if( msgValue != 0u)
                {
                    #ifdef Debug_Verbose2
                        DebugP_log("[CAN CORE] %s- msgValue [%#x] ioinstno[%d]  [%" PRId64 "]\r\n",__func__,msgValue,ioinstno,(ClockP_getTimeUsec()/1000));
                    #endif

                  msgValue |= (ioinstno + 1u);
                  if(CIP_Synch_Done)
                  {
                      IpcNotify_sendMsg(CSL_CORE_ID_R5FSS0_0, IOModules_IPC_ClientId, msgValue, 1);  //notify the CIP core response is ready
                  }
                }
            }//for(uint8_t ioinstno = 0; ioinstno < IO_INSTANCE_MAX; ioinstno++)
            //Update IO Acyclic Info to Main Core
            if(MainCore_Synch_Done)
            {
              xEventGroupSetBits(xAppMainCoreShmAccessEventGroup, MainCoreUpdtIOACyclic_WRBIT);
            }

            #ifdef Debug_Verbose2
                DebugP_log("IO Instance Acyclic Scan start[%" PRId64 "] end [%" PRId64 "] dur [%" PRId64 "]ms\r\n",scanstarted,(ClockP_getTimeUsec()/1000),((ClockP_getTimeUsec()/1000) -scanstarted ));
            #endif
        }//else if( ( uxBits & CIPACyclicEvntGrp_PrmUpdate_BIT ) != 0 )

            if( ( uxBits == 0u ) && (readacyclic <= 2) )
            {
                //DebugP_log("[CAN]After readacyclic[%d]\r\n",__func__,readacyclic);

                readacyclic++;
                xEventGroupSetBits(xACyclicEventGroup_IOModules, CIPACyclicEvntGrp_PrmUpdate_BIT);
            }*/

    }//for(;;)
}


/*!
 *  <!-- Description: -->
 *
 *  \brief
 *          This Task is used for Updating  IO Modules Acyclic Data  to SHM
 *          -  Getting the IO Modules   STATIC_CONSTANT_DATA , STATIC_CONFIG_DATA type Parameters Periodically untill available Status marked.
 *          -  Getting the IO Modules   Data as per Request from CIP Core. STATIC_VARIABLE_DATA Handles Request / Response events
 *
 *  <!-- Parameters and return values: -->
 *  \param[in]  pArgs_p         -    Not Used.
 *
 *  \return     None.
 */
void APP_IOModulesACyclicPrmUpdtTask(void* pArgs_p)
{
    //uint32_t    testitr = 0u;
    uint8_t     readacyclic = 0u;
    uint32_t    msgValue = 0;
    //AppRET_T sts = 0;
    EventBits_t uxBits;
    const TickType_t xTicksToWait =  Delay_Ms_Ticks(1000u);     //5000u

    // wait for a resource to be available Wait for lss to complete
    for(;;)
    {
        // Wait a maximum of 100ms for either bit 0 or bit 1 to be set within the event group. Clear the bits before exiting.
        uxBits = xEventGroupWaitBits(
                                    xAppStatusEventGroup,                               /* The event group being tested. */
                                    (const EventBits_t)(AppStsEvntGrpLSSComplete_BIT |
                                            AppStsEvntGrpSysConfigUpd_BIT),             /* The bits within the event group to wait for. */
                                    pdFALSE,                                            /* BIT_0 & BIT_4 should be cleared before returning. */
                                    pdTRUE,                                             /*  wait for all bits */
                                    portMAX_DELAY );                                    /* Wait a maximum of 100ms for either bit to be set. */

        if(  (uxBits & 0x05u)  == ( AppStsEvntGrpLSSComplete_BIT | AppStsEvntGrpSysConfigUpd_BIT) )
        {
                break;
        }
    }

     //vTaskDelay( 1000u );

    xEventGroupClearBits(xACyclicEventGroup_IOModules, CIPACyclicEvntGrp_PrmUpdate_BIT);

    for(;;)
    {
        // Wait a maximum of 100ms for either bit 0 or bit 1 to be set within the event group. Clear the bits before exiting.
        uxBits = xEventGroupWaitBits(
                            xACyclicEventGroup_IOModules,   /* The event group being tested. */
                            CIPACyclicEvntGrp_PrmUpdate_BIT, /* The bits within the event group to wait for.  |*/
                            pdFALSE,        /* BIT_0 & BIT_4 should be cleared before returning. */
                            pdFALSE,       /* Don't wait for both bits, either bit will do. */
                            xTicksToWait );/* Wait a maximum of 100ms for either bit to be set. */

        if( ( uxBits & CIPACyclicEvntGrp_PrmUpdate_BIT ) != 0 )
        {
            xEventGroupClearBits(xACyclicEventGroup_IOModules, CIPACyclicEvntGrp_PrmUpdate_BIT);

            if(SystemOperationMode == SERVICE_MODE) {
               vTaskDelay( 1000u );
               xEventGroupSetBits(xACyclicEventGroup_IOModules, CIPACyclicEvntGrp_PrmUpdate_BIT);      //fro Opr / Diag Data
               continue;
           }

            #ifdef Debug_Verbose2
                uint64_t    scanstarted = (ClockP_getTimeUsec()/1000);
                //DebugP_log("IO Instance Acyclic Scan started [%" PRId64 "]ms\r\n",(ClockP_getTimeUsec()/1000));
            #endif

            uint8_t boardtype = IO_NONE;
            for(uint8_t ioinstno = 0; ioinstno < IO_INSTANCE_MAX; ioinstno++)
            {
                //get Board Type of instance  and get all service parameters and update SHM and parameter avail status

                boardtype = iomodulediscoveryinfo[ioinstno].BoardId;
                if(boardtype == IO_NONE)  {
                    break;
                }

                msgValue = 0u;

                switch(boardtype)
                {
                    case    DI_M8:
                    case    DI_M12:
                                    if( Process_DI_AcyclicData(ioinstno, DI_XX) == APPAcyclicDataChanged) {
                                        msgValue = IOACYCLIC_DI_NOTIFY_ID;
                                    }
                                    break;
                    case    DIO_M8:
                    case    DIO_M12:
                                    if( Process_DIO_AcyclicData(ioinstno) == APPAcyclicDataChanged) {
                                        msgValue = IOACYCLIC_DIO_NOTIFY_ID;
                                    }
                                    break;
                    case    DO_M8:
                    case    DO_M12:
                                    if(Process_DO_AcyclicData(ioinstno, DO_XX) == APPAcyclicDataChanged) {
                                        msgValue = IOACYCLIC_DO_NOTIFY_ID;
                                    }
                                    break;
                    case    AI_M12:
                                    if(Process_AI_AcyclicData(ioinstno, AI_XX) == APPAcyclicDataChanged) {
                                        msgValue = IOACYCLIC_AI_NOTIFY_ID;
                                    }
                                    break;
                    case    AO_M12:
                                    if(Process_AO_AcyclicData(ioinstno, AO_XX) == APPAcyclicDataChanged) {
                                        msgValue = IOACYCLIC_AO_NOTIFY_ID;
                                    }
                                    break;
                    case    AIO_M12:
                                    if(Process_AIO_AcyclicData(ioinstno) == APPAcyclicDataChanged) {
                                        msgValue = IOACYCLIC_AIO_NOTIFY_ID;
                                    }
                                    break;
                    default:
                                    break;
                }//switch(boardtype)

                if( msgValue != 0u)
                {
                    msgValue |= (ioinstno + 1u);

                    #ifdef Debug_Verbose2
                        DebugP_log("[CAN CORE] %s- msgValue [%#x] ioinstno[%d] CIP_Synch_Done[%d] [%" PRId64 "]\r\n",__func__,msgValue,ioinstno,CIP_Synch_Done,(ClockP_getTimeUsec()/1000));
                    #endif

                  if(CIP_Synch_Done) {
                      IpcNotify_sendMsg(CSL_CORE_ID_R5FSS0_0, IOModules_IPC_ClientId, msgValue, 1);  //notify the CIP core response is ready
                  }
                }
            }//for(uint8_t ioinstno = 0; ioinstno < IO_INSTANCE_MAX; ioinstno++)
            //Update IO Acyclic Info to Main Core
            if(MainCore_Synch_Done) {
              xEventGroupSetBits(xAppMainCoreShmAccessEventGroup, MainCoreUpdtIOACyclic_WRBIT);
            }

            #ifdef Debug_Verbose2
                DebugP_log("IO Instance Acyclic Scan start[%" PRId64 "] end [%" PRId64 "] dur [%" PRId64 "]ms\r\n",scanstarted,(ClockP_getTimeUsec()/1000),((ClockP_getTimeUsec()/1000) -scanstarted ));
            #endif

            //Update PZx Acyclic Datas to SHM
            PZx_ParamScanAndUpdate();

        }//if( ( uxBits & CIPACyclicEvntGrp_PrmUpdate_BIT ) != 0 )
/*
        //if( ( uxBits == 0u ) && (readacyclic == 2) )
        if( readacyclic == 2 )
        {
            //vTaskDelay(200u);
            readacyclic = 0u;
            xEventGroupSetBits(xACyclicEventGroup_IOModules, CIPACyclicEvntGrp_PrmUpdate_BIT);
        }
        else
            readacyclic++;      //xEventGroupSetBits(xACyclicEventGroup_IOModules, CIPACyclicEvntGrp_PrmUpdate_BIT);      //fro Opr / Diag Data
*/

        if( readacyclic <= 2 )
        {
            readacyclic++;
           //vTaskDelay(200u);
           //readacyclic = 0u;
           xEventGroupSetBits(xACyclicEventGroup_IOModules, CIPACyclicEvntGrp_PrmUpdate_BIT);
        }


    }//for(;;)
}

