/*
 * DataSyncPzTasks.c
 *
 *  Created on: Nov 17, 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 "CIPCoreExterns.h"


/*!
 *  <!-- Description: -->
 *
 *  \brief
 *
 *   PZx 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
 */
 AppRET_T pzx_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_PZx_mutexObj, 10u);
    if(sempstatus != SystemP_SUCCESS) {
               return AppGetSHMLockErr;
    }

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

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

      //vTaskDelay( 1u );
      __asm__ volatile ("nop");
    }
    if(timeout == 0u) {
      return AppGetSHMLockTimeOutErr;
    }

    return AppRET_OK;
}

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

    return;
}

/*!
 *  <!-- Description: -->
 *
 *  \brief
 *
 *   PZx 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 pzx_sharemem_acycliclock(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(&ACyclic_PZx_mutexObj, 10u);
    if(sempstatus != SystemP_SUCCESS) {
               return AppGetSHMLockErr;
    }

    /* Spin till lock is acquired or timeout*/
    for(;;)
    {
      status = Spinlock_lock(spinlockBaseAddr, SPINLOCKNO_ACYCLIC_PZx);
      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
 *
 *   PZx Release Shared Memory Lock
 *
 *  <!-- Parameters and return values: -->
 *  \param[in] : None
 *  \return    : None
 */
void pzx_sharemem_acyclicunlock(void)
{
    // Free the aquired lock and release local mutex
    Spinlock_unlock(spinlockBaseAddr, SPINLOCKNO_ACYCLIC_PZx);
    SemaphoreP_post(&ACyclic_PZx_mutexObj);

    return;
}



/*!
 *  <!-- Description: -->
 *
 *  \brief
 *          This Task is used for Getting PZx Modules(ISEM Backplane/ISEM-DIAG/DIAG-Valve/Prop Acyclic Data from BackPlane
 *          -  Getting the PZx Modules   STATIC_CONSTANT_DATA , STATIC_CONFIG_DATA type Parameters Periodically untill available Status marked.
 *          -  Getting the PZx 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_PZxModulesACyclicTask(void* pArgs_p)
{
    //uint8_t     readacyclic = 0u;
    //uint32_t    msgValue = 0;
    AppRET_T sts = 0;
    EventBits_t uxBits;
    const TickType_t xTicksToWait =  Delay_Ms_Ticks(5000u);
    pzacyclic_client_reqresp     pzxacyclicreq;
    pzacyclic_client_reqresp     pzacyclicresp;

    /* 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. */
                                    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 != 0u) {
                break;
        }
    }
    //vTaskDelay( 100u );

    xEventGroupClearBits(xACyclicEventGrp_PZxModules, CIPACyclicEventGrp_WRReq_BIT  | CIPACyclicEventGrp_RDReq_BIT | CIPACyclicEventGrp_Resp_BIT | 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(
                xACyclicEventGrp_PZxModules,                                                    /* The event group being tested. */
                            CIPACyclicEventGrp_WRReq_BIT  | CIPACyclicEventGrp_RDReq_BIT |
                            CIPACyclicEventGrp_Resp_BIT | 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. */

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

            //pzacyclic_client_reqresp     pzxacyclicreq;
            //sts = pzx_sharemem_acycliclock();
            //if(sts == AppRET_OK)
            {
                pzxacyclicreq = PZxAcyclic_WRRequest;
                pzxacyclicreq.reqclient = CLIENT_CIP_IO;


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

                #endif

            //pzx_sharemem_acyclicunlock();
            }//if(sts == AppRET_OK)
            if( (pzxacyclicreq.BoardId != IO_NONE) && (pzxacyclicreq.rwmode == DATA_WR) )
            {
                    PZxAcyclicWRReqProcess = 1u;

                    AppRET_T sts1;
                    sts1 = Process_PZx_ACyclic_req(&pzxacyclicreq);

                    /*update req response status to SHM send  notify to CIP.*/
                    if(sts1 == APPAcyclicDataChanged)
                    {
                        sts = pzx_sharemem_acycliclock();
                        if(sts == AppRET_OK)
                        {
                            //pzacyclic_client_reqresp     pzxacyclicresp;

                            pzacyclicresp = pzxacyclicreq;
                            pzacyclicresp.respsts = sts1;

                            PZxAcyclic_WRResponse = pzacyclicresp;

                            PZxAcyclic_WRRequest.BoardId = IO_NONE;

                            pzx_sharemem_acyclicunlock();

                            //Add later the resp to CIP  * may not be required already uodate in wr call
                            //msgValue = 0u;
                            //msgValue |= IOACYCLIC_NOTIFY_ID | ioacyclicresp.PosId;     //lATER ADD SPECIFIC TYPES
                            //IpcNotify_sendMsg(CSL_CORE_ID_R5FSS0_0, PZxModules_IPC_ClientId, msgValue, 1);  //notify the CIP core response is ready

                        }//if(sts == AppRET_OK)

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

                    }/*if(sts1 == APPAcyclicDataChanged)*/

                    PZxAcyclicWRReqProcess = 0u;
            }

        }/*if( ( uxBits & CIPACyclicEventGrp_WRReq_BIT ) != 0 )*/
        else if( ( uxBits & CIPACyclicEventGrp_RDReq_BIT ) != 0 )
        {
            xEventGroupClearBits(xACyclicEventGrp_PZxModules, 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

            //sts = pzx_sharemem_acycliclock();
            //if(sts == AppRET_OK)
            {
                pzxacyclicreq = PZxAcyclic_RDRequest;
                pzxacyclicreq.reqclient = CLIENT_CIP_IO;

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

            #ifdef Debug_Verbose2
                DebugP_log("[CAN CORE] %s- pzxacyclicreq.BoardId[%#x] pzxacyclicreq.rwmode[%d] started[%" PRId64 " ms]\r\n",__func__,pzxacyclicreq.BoardId,pzxacyclicreq.rwmode,started);
            #endif

            if( (pzxacyclicreq.BoardId != IO_NONE) && (pzxacyclicreq.rwmode == DATA_RD) )
            {
                PZxAcyclicRDReqProcess = 1u;

                AppRET_T   sts2;

                if( (pzxacyclicreq.ParamId >= DiagValPort2PressureCurves) && (pzxacyclicreq.ParamId <= DiagValCoil14Curves)) {

                   sts2 = Process_PZx_CurveData_req(&pzxacyclicreq);
               }
               else {

                   sts2 = Process_PZx_ACyclic_req(&pzxacyclicreq);
               }

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

                sts = pzx_sharemem_acycliclock();
                if(sts == AppRET_OK)
                {
                    /*update req response status to SHM send  notify to CIP.*/
                    if(sts2 == APPAcyclicDataChanged)
                    {
    //                    sts = pzx_sharemem_acycliclock();
    //                    if(sts == AppRET_OK)
    //                    {
                            //pzacyclic_client_reqresp     pzacyclicresp;

                            pzacyclicresp = pzxacyclicreq;
                            pzacyclicresp.respsts = 0;

                            PZxAcyclic_RDResponse = pzacyclicresp;

                            PZxAcyclic_RDRequest.BoardId = IO_NONE;

                            #ifdef Debug_Verbose2
                                DebugP_log("[[CAN CORE] %s started[%" PRId64 " ms] [%" PRId64 " ms] PZxAcyclic_RDRequest.BoardId[%#x] PZxAcyclic_RDResponse.respsts[%#x]\r\n",__func__,started,(ClockP_getTimeUsec()/1000u),PZxAcyclic_RDRequest.BoardId,PZxAcyclic_RDResponse.respsts);
                            #endif

//                            pzx_sharemem_acyclicunlock();

                            /*msgValue = 0u;
                            //uint8_t boardtype = pzxacyclicreq.BoardId;    //valvemodulediscoveryinfo[posno].BoardId;
                            uint8_t moduletype = pzxacyclicreq.Moduletype;
                            //update to pzx SHM
                            switch(moduletype)
                            {
                                case    ISEM_VALVE_BACKPLANE:
                                                            msgValue = PZACYCLIC_ISEMBASE_NOTIFY_ID;
                                                            break;
                                case    ISEMDIAG_MODULE:
                                                            msgValue = PZACYCLIC_ISEMDIAG_NOTIFY_ID;
                                                            break;
                                case    DIAGVALVE_MODULE:
                                                            msgValue = PZACYCLIC_DIAGVAL_NOTIFY_ID;
                                                            break;
                                case PROP_VALVE_BACKPLANE:
                                                            msgValue = PZACYCLIC_PROPBASE_NOTIFY_ID;
                                                            break;
                                case PROPVALVE_MODULE:
                                                            msgValue = PZACYCLIC_PROPVAL_NOTIFY_ID;
                                                            break;
                                default:
                                            break;
                            }//switch(boardtype)

                            if( msgValue != 0u)
                            {
                             msgValue |= (pzxacyclicreq.PosId);
                             if(CIP_Synch_Done)
                             {
                                 IpcNotify_sendMsg(CSL_CORE_ID_R5FSS0_0, PZxModules_IPC_ClientId, msgValue, 1);  //notify the CIP core response is ready
                             }

                                #ifdef Debug_Verbose2
                                  DebugP_log("[CAN CORE] %s- msgValue [%#x] pzid[%d]  [%" PRId64 "]\r\n",__func__,msgValue,pzxacyclicreq.PosId,(ClockP_getTimeUsec()/1000));
                                #endif
                            }*/

//                        }//if(sts == AppRET_OK)
                    }//if(sts1 == APPAcyclicDataChanged)
                    else {
                        PZxAcyclic_RDRequest.BoardId = IO_NONE;
                        PZxAcyclic_RDRequest.respsts = 1;
                    }
                pzx_sharemem_acyclicunlock();
            }//if(sts == AppRET_OK)
                PZxAcyclicRDReqProcess = 0u;

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

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

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

           //uint8_t boardtype = VALVE_NONE;
           for(uint8_t pzindex = 0; pzindex < pz_availcnt; pzindex++)
           {
               //get Module Type of instance  and get all service parameters and update SHM and parameter avail staMainCore_Synch_Done[%d]tus

               //DebugP_log("Pzx Instance Acyclic Scan started pzindex[%d] pz_availcnt[%d] CIP_Synch_Done[%d] MainCore_Synch_Done[%d] [%" PRId64 "]ms\r\n",pzindex,pz_availcnt,CIP_Synch_Done,MainCore_Synch_Done,(ClockP_getTimeUsec()/1000));

                uint8_t  pzid = pz_moduleinfo[pzindex].PressureZoneId;
                if(pzid == 0u)
                {
                    break;
                }

                for(uint8_t instno = 0; instno < 5u; instno++)
                {
                    msgValue = 0u;
                    switch(instno)
                    {
                        case    0u:
                                    if( Process_ISEMBASE_AcyclicData(pzid) == APPAcyclicDataChanged)
                                    {
                                               msgValue = PZACYCLIC_ISEMBASE_NOTIFY_ID;
                                    }
                                    break;
                        case    1u:
                                    if(pz_moduleinfo[pzindex].isemdiagnosticPresent)
                                    {
                                        if( Process_ISEMDIAG_AcyclicData(pzid) == APPAcyclicDataChanged)
                                        {
                                            msgValue = PZACYCLIC_ISEMDIAG_NOTIFY_ID;
                                        }
                                    }
                                    break;
                        case    2u:
                                    if(pz_moduleinfo[pzindex].diagvalvePresentCnt)
                                    {
                                        if( Process_DIAGVALVE_AcyclicData(pzid) == APPAcyclicDataChanged)
                                        {
                                            msgValue = PZACYCLIC_DIAGVAL_NOTIFY_ID;
                                        }
                                    }
                                    break;
                        case    3u:
                                    if(pz_moduleinfo[pzindex].PropTypePresent)
                                    {
                                        //if( Process_PROPBASE_AcyclicData(pzid) == APPAcyclicDataChanged)
                                            //msgValue = PZACYCLIC_PROPBASE_NOTIFY_ID;
                                    }
                                    break;
                        case    4u:
                                    if(pz_moduleinfo[pzindex].PropTypePresent)
                                    {
                                        if( Process_PROPVALVE_AcyclicData(pzid) == APPAcyclicDataChanged)
                                        {
                                            msgValue = PZACYCLIC_PROPVAL_NOTIFY_ID;
                                        }
                                    }
                                    break;
                    }

                    if( msgValue != 0u)
                    {
                        msgValue |= (pzid);
                        if(CIP_Synch_Done)
                        {
                            #ifdef Debug_Verbose2
                                DebugP_log("[CAN CORE] %s- msgValue [%#x] pzid[%d]  [%" PRId64 "] CIP_Synch_Done[%d]\r\n",__func__,msgValue,pzid,(ClockP_getTimeUsec()/1000),CIP_Synch_Done);
                            #endif
                            IpcNotify_sendMsg(CSL_CORE_ID_R5FSS0_0, PZxModules_IPC_ClientId, msgValue, 1);  //notify the CIP core response is ready
                        }
                    }//if( msgValue != 0u)
                }//for(uint8_t instno = 0; instno < 5u; instno++)

           }//for(uint8_t pzindex = 0; pzindex < pz_availcnt; pzindex++)

           //Update IO Acyclic Info to Main Core
           if(MainCore_Synch_Done)
           {
               xEventGroupSetBits(xAppMainCoreShmAccessEventGroup, MainCoreUpdtPZxACyclic_WRBIT);
           }

        }//else if( ( uxBits & CIPACyclicEvntGrp_PrmUpdate_BIT ) != 0 )

        if( ( uxBits == 0u ) && (readacyclic <= 2) )
        {
            readacyclic++;
            xEventGroupSetBits(xACyclicEventGrp_PZxModules, CIPACyclicEvntGrp_PrmUpdate_BIT);
        }*/

        taskYIELD();

    }/*for(;;)*/
}


void PZx_ParamScanAndUpdate(void)
{
    uint32_t    msgValue = 0;

    for(uint8_t pzindex = 0; pzindex < pz_availcnt; pzindex++)
    {
        //get Module Type of instance  and get all service parameters and update SHM and parameter avail staMainCore_Synch_Done[%d]tus

        //DebugP_log("Pzx Instance Acyclic Scan started pzindex[%d] pz_availcnt[%d] CIP_Synch_Done[%d] MainCore_Synch_Done[%d] [%" PRId64 "]ms\r\n",pzindex,pz_availcnt,CIP_Synch_Done,MainCore_Synch_Done,(ClockP_getTimeUsec()/1000));

        //DebugP_log("Pzx Instance Acyclic Scan pzindex[%d] pz_availcnt[%d] started[%" PRId64 "]ms ",pzindex,pz_availcnt,(ClockP_getTimeUsec()/1000));


         uint8_t  pzid = pz_moduleinfo[pzindex].PressureZoneId;
         if(pzid == 0u) {
             break;
         }

         for(uint8_t instno = 0; instno < 5u; instno++)
         {
             msgValue = 0u;
             switch(instno)
             {
                 case    0u:
                             if( Process_ISEMBASE_AcyclicData(pzid) == APPAcyclicDataChanged) {
                                        msgValue = PZACYCLIC_ISEMBASE_NOTIFY_ID;
                             }
                             break;
                 case    1u:
                             if(pz_moduleinfo[pzindex].isemdiagnosticPresent)
                             {
                                 if( Process_ISEMDIAG_AcyclicData(pzid) == APPAcyclicDataChanged) {
                                     msgValue = PZACYCLIC_ISEMDIAG_NOTIFY_ID;
                                 }
                             }
                             break;
                 case    2u:
                             if(pz_moduleinfo[pzindex].diagvalvePresentCnt)
                             {
                                 if( Process_DIAGVALVE_AcyclicData(pzid) == APPAcyclicDataChanged) {
                                     msgValue = PZACYCLIC_DIAGVAL_NOTIFY_ID;
                                 }
                             }
                             break;
                 case    3u:
                             if(pz_moduleinfo[pzindex].PropTypePresent)
                             {
                                 //if( Process_PROPBASE_AcyclicData(pzid) == APPAcyclicDataChanged)
                                     //msgValue = PZACYCLIC_PROPBASE_NOTIFY_ID;
                             }
                             break;
                 case    4u:
                             if(pz_moduleinfo[pzindex].PropTypePresent)
                             {
                                 if( Process_PROPVALVE_AcyclicData(pzid) == APPAcyclicDataChanged) {
                                     msgValue = PZACYCLIC_PROPVAL_NOTIFY_ID;
                                 }
                             }
                             break;
                 default:
                             break;
             }

             if( msgValue != 0u)
             {
                msgValue |= (pzid);

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

                if(CIP_Synch_Done) {
                    IpcNotify_sendMsg(CSL_CORE_ID_R5FSS0_0, PZxModules_IPC_ClientId, msgValue, 1);  //notify the CIP core response is ready
                }
             }//if( msgValue != 0u)
         }//for(uint8_t instno = 0; instno < 5u; instno++)

         //DebugP_log("  CIP_Synch_Done[%d] MainCore_Synch_Done[%d] Ended[%" PRId64 "]ms\r\n",pzindex,pz_availcnt,CIP_Synch_Done,MainCore_Synch_Done,(ClockP_getTimeUsec()/1000));

    }//for(uint8_t pzindex = 0; pzindex < pz_availcnt; pzindex++)

    //Update IO Acyclic Info to Main Core
    if(MainCore_Synch_Done) {
        xEventGroupSetBits(xAppMainCoreShmAccessEventGroup, MainCoreUpdtPZxACyclic_WRBIT);
    }

    return;
}

/*!
 *  <!-- Description: -->
 *
 *  \brief
 *
 *   PZx-Standard-Valve /ISEM DIAG / DIAG-VALVE/INTR PROP Modules Data Sync Req/Resp Task From CIP Core
 *
 *  <!-- Parameters and return values: -->
 *  \param[in] : * pArgs_p  Not Used
 *  \return    : None
 */
void APP_PZxCyclicTask(void* pArgs_p)
{
    uint8_t updatetomaincore = 0u;
    AppRET_T sts = 0;
    EventBits_t uxBits;
    const TickType_t xTicksToWait =  Delay_Ms_Ticks(5000u);
    //uint32_t msg_identifier[] = {PZCYCLIC_STNDVALERR_NOTIFY_ID, PZCYCLIC_ISEMDIAGPDI_NOTIFY_ID, PZCYCLIC_DIAGVALVEPDI_NOTIFY_ID,PZCYCLIC_PROPPDI_NOTIFY_ID};

    /*wait for a resource to be available Wait for lss to complete*/
    while(1u)
    {

        // 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. */
                                    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 != 0x00u) {
                break;
        }
    }

    //vTaskDelay( 250u );

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

        xQueueReset(ipcmsgcyclicstnopqueue);
        xQueueReset(pzx_shmdataupdwrqueue);
        xQueueReset(ipcmsgcyclicpropopqueue);
        xQueueReset(ipcmsgcyclicextpropopqueue);

        xEventGroupClearBits(xCyclicEventGrp_PZx, CIPCyclicEvntGrpPZx_STNOP_BIT  | CIPCyclicEventGrp_InputSts_BIT |
                                                             CIPCyclEntGrpPZx_IsemDiagOPBIT |
                                                             CIPCyclEntGrpPZx_DiagValOPBIT  |
                                                             CIPCyclEntGrpPZx_INTPropOPBIT  |
                                                             CIPCyclEntGrpPZx_EXTPropOPBIT );


        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(
                                xCyclicEventGrp_PZx,                                                /* The event group being tested. */
                                CIPCyclicEvntGrpPZx_STNOP_BIT  | CIPCyclicEventGrp_InputSts_BIT |
                                //CIPCyclEntGrpPZx_IsemDiagOPBIT | CIPCyclEntGrpPZx_DiagValOPBIT  |
                                CIPCyclEntGrpPZx_INTPropOPBIT | CIPCyclEntGrpPZx_EXTPropOPBIT,      /* 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

            //Cyclic Output Data received from CIP send to Backplane
            if( ( uxBits & CIPCyclicEvntGrpPZx_STNOP_BIT ) != 0 )
            {
                #ifdef Debug_Verbose2
                    DebugP_log("[[CAN] if( ( uxBits & CIPCyclicEvntGrpPZx_STNOP_BIT ) != 0 \r\n");
                #endif

                xEventGroupClearBits(xCyclicEventGrp_PZx, CIPCyclicEvntGrpPZx_STNOP_BIT);

                if(uxQueueMessagesWaiting(ipcmsgcyclicstnopqueue))
                {
                    ipc_pzxcyclicmsgprocess ipccyclicpzxmsg = {0u};

                    if(xQueueReceive(ipcmsgcyclicstnopqueue, &(ipccyclicpzxmsg), (TickType_t)MSGQUEUE_RECV_TO) )
                    {
                        //sts = pzx_sharemem_cycliclock();
                        //if(sts == AppRET_OK)
                        {
                            Process_PZxStandardValve_CyclicOutputSts(ipccyclicpzxmsg.PzNo);

                            //pzx_sharemem_cyclicunlock();
                        }//if(sts == 0)
                    }
                }
            }//if( ( uxBits & CIPCyclicEvntGrpPZx_STNOP_BIT ) != 0 )
            else if( ( uxBits & CIPCyclEntGrpPZx_INTPropOPBIT ) != 0 )
            {
                xEventGroupClearBits(xCyclicEventGrp_PZx, CIPCyclEntGrpPZx_INTPropOPBIT);

                if(uxQueueMessagesWaiting(ipcmsgcyclicpropopqueue))
                {
                    ipc_pzxcyclicmsgprocess ipccyclicpzxmsg ={0u};

                    if(xQueueReceive(ipcmsgcyclicpropopqueue, &(ipccyclicpzxmsg), (TickType_t)MSGQUEUE_RECV_TO) )
                    {
                        //sts = pzx_sharemem_cycliclock();
                        //if(sts == AppRET_OK)
                        {
                            Process_PZxIntProp_CyclicPdo(ipccyclicpzxmsg.PzNo);

                            //pzx_sharemem_cyclicunlock();
                        }
                    }
                }
            }//if( ( uxBits & CIPCyclEntGrpPZx_INTPropOPBIT ) != 0 )
            else if( ( uxBits & CIPCyclEntGrpPZx_EXTPropOPBIT ) != 0 )
            {
                xEventGroupClearBits(xCyclicEventGrp_PZx, CIPCyclEntGrpPZx_EXTPropOPBIT);

                if(uxQueueMessagesWaiting(ipcmsgcyclicextpropopqueue))
                {
                    ipc_pzxcyclicmsgprocess ipccyclicpzxmsg ={0u};

                    if(xQueueReceive(ipcmsgcyclicextpropopqueue, &(ipccyclicpzxmsg), (TickType_t)MSGQUEUE_RECV_TO) )
                    {
                        //sts = pzx_sharemem_cycliclock();
                        //if(sts == AppRET_OK)
                        {
                            Process_PZxExtProp_CyclicPdo(ipccyclicpzxmsg.PzNo);

                            //pzx_sharemem_cyclicunlock();
                        }
                    }
                }
            }//if( ( uxBits & CIPCyclEntGrpPZx_PropOPBIT ) != 0 )


            updatetomaincore = 0u;
            if( ( uxBits & CIPCyclicEventGrp_InputSts_BIT ) != 0 )
            {
                #ifdef Debug_Verbose2
                    DebugP_log("[[CAN] if( ( uxBits & CIPCyclicEventGrp_InputSts_BIT ) != 0 \r\n");
                #endif

                //edit later
                //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(pzx_shmdataupdwrqueue);
                if(msgcnt != 0u)
                {
                    sts = pzx_sharemem_cycliclock();
                    if(sts == AppRET_OK)
                    {
                        PZxCyclicData_SHMUpdate_Info   pxodDataMessage = {0};
                        for(uint8_t cntr = 0; cntr < (uint8_t)msgcnt; cntr++)
                        {
                            if(xQueueReceive(pzx_shmdataupdwrqueue, &(pxodDataMessage), (TickType_t)MSGQUEUE_RECV_TO) )
                            {
                                //uint32_t msgValue = PZMODULEMSG_NOTIFY_ID;

                                AppRET_T sts = Process_PZx_CyclicInputSts_SHM(&pxodDataMessage);
                                if(sts == APPCyclicDataChanged) {
                                        updatetomaincore = 1u;
                                }

                                /*if( (sts == AppRET_OK) && (pxodDataMessage.paramtype >= IPC_PZSTA_ERR_DATA) )
                                {
                                    //msgValue |= msg_identifier[ pxodDataMessage.paramtype - IPC_PZSTA_ERR_DATA];

                                     // ADD pxodDataMessage.instanceno IF dv TO MSGvALUE********

                                    if( pxodDataMessage.paramtype == IPC_PZSTA_ERR_DATA)
                                        msgValue = PZCYCLIC_STNDVALERR_NOTIFY_ID;
                                    else if( pxodDataMessage.paramtype == IPC_PZISEMDIAG_PDI_DATA )
                                        msgValue = PZCYCLIC_ISEMDIAGPDI_NOTIFY_ID;
                                    else if( pxodDataMessage.paramtype == IPC_PZDIAGVALVE_PDI_DATA )
                                        msgValue = PZCYCLIC_DIAGVALVEPDI_NOTIFY_ID;
                                    else if( pxodDataMessage.paramtype == IPC_PZDIAGVALVE_ERR_DATA )
                                        msgValue = PZCYCLIC_DIAGVALVEERR_NOTIFY_ID;
                                    else if( pxodDataMessage.paramtype == IPC_PROP_PDI_DATA )
                                        msgValue = PZCYCLIC_PROPPDI_NOTIFY_ID;
                                    else if( pxodDataMessage.paramtype == IPC_PROP_OUTPUTPORTPRESSURE )
                                        msgValue = PZCYCLIC_PROPOPPRESS_NOTIFY_ID;

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

                                    #ifdef Debug_Verbose2
                                        DebugP_log("[[CAN] if( ( uxBits & CIPCyclicEventGrp_InputSts_BIT ) msgValue[%#x]\r\n",msgValue);
                                    #endif

                                }//if(pxodDataMessage.paramtype >= IPC_PZSTA_ERR_DATA)*/

                            }//if(xQueueReceive(io_shmdataupdwrqueue, &(pxodDataMessage), (TickType_t)MSGQUEUE_RECV_TO) )
                        }

                        pzx_sharemem_cyclicunlock();

                    }//if(sts == AppRET_OK)
                }/*if(uxQueueMessagesWaiting(io_shmdataupdwrqueue) != 0u)*/
                if(uxQueueMessagesWaiting(pzx_shmdataupdwrqueue) == 0u) {

                       xEventGroupClearBits(xCyclicEventGrp_PZx, CIPCyclicEventGrp_InputSts_BIT);
                }
            }

            /* reserved for futher use*******************************************************************
            if( ( uxBits & CIPCyclEntGrpPZx_IsemDiagOPBIT ) != 0 )
            {
                xEventGroupClearBits(xCyclicEventGrp_PZx, CIPCyclEntGrpPZx_IsemDiagOPBIT);

                sts = pzx_sharemem_cycliclock();
                if(sts == AppRET_OK)
                {
                    //Process_PZ1ISEMDIAG_CyclicPdo();

                    pzx_sharemem_cyclicunlock();
                }
            }
            //else ds

            if( ( uxBits & CIPCyclEntGrpPZx_DiagValOPBIT ) != 0 )
            {
                xEventGroupClearBits(xCyclicEventGrp_PZx, CIPCyclEntGrpPZx_DiagValOPBIT);

                sts = pzx_sharemem_cycliclock();
                if(sts == AppRET_OK)
                {
                    //Process_PZ1DIAGValve_CyclicPdo();

                    pzx_sharemem_cyclicunlock();
                }
            }
            //else ds
            reserved for futher use********************************************************************/


            if(updatetomaincore)
            {
                #ifdef Debug_Verbose2
                    DebugP_log("[[CAN] %s updatetomaincore[%d] MainCore_Synch_Done[%d]\r\n",__func__,updatetomaincore,MainCore_Synch_Done);
                #endif

                /*Update PZx Modules Cyclic Info  to Main Core*/
                if(MainCore_Synch_Done) {
                  xEventGroupSetBits(xAppMainCoreShmAccessEventGroup, MainCoreUpdtPZxCyclic_WRBIT);
                }
            }

            #ifdef Debug_Verbose2
                DebugP_log("[[CAN] %s start[%" PRId64 "] end[%" PRId64 "] uxBits[%#x]\r\n",__func__,start,(ClockP_getTimeUsec()/1000u),uxBits);
            #endif

            taskYIELD();
        }//for(;;)
}

