/*
 * SHMSysCfgStsDataSyncTasks.c
 *
 *  Created on: Dec 5, 2024
 *      Author: tummalanr
 */



#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <stdarg.h>

#include <inttypes.h>
#include <kernel/dpl/DebugP.h>
#include <kernel/dpl/SemaphoreP.h>
#include <kernel/dpl/ClockP.h>
#include <drivers/spinlock.h>
#include <drivers/ipc_notify.h>

#include <drivers/ipc_rpmsg.h>
#include <kernel/dpl/AddrTranslateP.h>
#include <kernel/dpl/EventP.h>
#include "FreeRTOS.h"
#include "task.h"



#include    "SystemStsConfig.h"
#include    "IPCDataSyncGlobal.h"
#include    "AppSharedMemory.h"
#include    "EepromAccessExtern.h"
#include    "SharedMemoryExterns.h"


uint32_t   SystemStatusConfigReqIDs[SHM_Max_ReqIds] = {0u};
uint8_t    sysstscnfgreqidindex = 0u;
uint8_t    CAN_ModuleDiscovery_Finished = 0u;

//Data IN SHARED MEMORY******************************************************

//Shared Memory Declarations for System Status and Config for all modules*************************************************************


//#define INIT_SYSTEM_DISCOVERY_STATUS(sys_disc_sts) system_discoverystatusinfo sys_disc_sts = {.ModuleDiscoveryStatus = 0xffu, .DiscoveredIOModuleCnt =0u, .DiscoveredPZModuleCnt = 0u, .IO_Discovered_ModulesType = {0xffu}, .Pz_Details = {0u}}


//Shared Memory Declarations for System Status and Config for all modules*************************************************************

system_discoverystatusinfo  app_sys_discvrystsinfo =  {.ModuleDiscoveryStatus = 0xffu};



/*!
 *  <!-- Description: -->
 *
 *  \brief
 *
 *   System Status Config Acquire Shared Memory Lock for Processing IPC System Info  Messages/Data
 *
 *  <!-- Parameters and return values: -->
 *  \param[in] :None
 *  \return    :
 *              AppRET_T  : AppRET_OK on Success or Error
 */
AppRET_T sysinfo_sharemem_lock(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(&System_Info_mutexObj, 10u);       //SystemP_WAIT_FOREVER   10000
    if(sempstatus != SystemP_SUCCESS) {
               return AppGetSHMLockErr;
    }

    // Spin till lock is acquired or timeout
    for(;;)
    {
      status = Spinlock_lock(spinlockBaseAddr, SPINLOCKNO_SYSTEM_INFO);
      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
 */
void sysinfo_sharemem_unlock(void)
{
    // Free the aquired lock and release local mutex
    Spinlock_unlock(spinlockBaseAddr, SPINLOCKNO_SYSTEM_INFO);
    SemaphoreP_post(&System_Info_mutexObj);

    return;
}

/*!
 *  <!-- Description: -->
 *
 *  \brief
 *          This Task is used for Processing System Config / Info IPC Notify Messages received from CAN CORE indicating Data Updation's in Shared Memory
 *
 *  <!-- Parameters and return values: -->
 *  \param[in]  pArgs_p         -    Not Used.
 *
 *  \return     None.
 */
void APP_SHM_SysConfigStsRDWRTask(void* pArgs_p)
{
    AppRET_T    sts = 0u;
    uint8_t     indx = 0u;
    int32_t     status;
    uint32_t    msgValue = 0u;
    uint32_t    eventBits;


    status = EventP_clearBits(&gSysConfigSts_DataRDWRSynchEvent, (System_StatusConfig_RDWREvnt_BIT ) );
    DebugP_assert(SystemP_SUCCESS == status);

    for(;;)
    {
        status = EventP_waitBits(&gSysConfigSts_DataRDWRSynchEvent, System_StatusConfig_RDWREvnt_BIT, 0u, 0u, SystemP_WAIT_FOREVER, &eventBits);
        if(status == SystemP_SUCCESS )
        {
            if(eventBits & System_StatusConfig_RDWREvnt_BIT)
            {
                #ifdef Debug_VerboseSHM
                    DebugP_log("[CIP] %s RD Event Triggered  %" PRId64 " ms\r\n",__func__,ClockP_getTimeUsec()/1000);
                    //started = ClockP_getTimeUsec()/1000;
                #endif

                //sts = sysinfo_sharemem_lock();
                //if(sts == AppRET_OK)
                {
                    for( indx = 0; indx < SHM_Max_ReqIds; indx++ )
                    {
                        uint8_t     done = 1u;
                        msgValue = SystemStatusConfigReqIDs[indx];


                        #ifdef Debug_VerboseSHM
                          DebugP_log("[CIP] %s [indx %d] msgValue : %#x  %" PRId64 " ms\r\n",__func__,indx,msgValue,ClockP_getTimeUsec()/1000);

                        #endif

                          if(msgValue == 0u) {
                                 continue;
                          }
                          break;

                    }//for(uint8_t indx = 0; indx < SHM_Max_ReqIds; indx++ )
                    SystemStatusConfigReqIDs[indx] = 0u;
                    //sysinfo_sharemem_unlock();
                }//if(sts == AppRET_OK)



                #ifdef Debug_VerboseSHM2
                    DebugP_log("[CIP] %s Read Completed... CAN_ModuleDiscovery_Finished[%d] %" PRId64 " ms\r\n",__func__,CAN_ModuleDiscovery_Finished,ClockP_getTimeUsec()/1000);
                #endif

        }//if(status == SystemP_SUCCESS )

            for( indx = 0; indx < SHM_Max_ReqIds; indx++ ) {
                if( SystemStatusConfigReqIDs[indx] != 0u) {
                        break;
                }
            }
             if(indx == SHM_Max_ReqIds )  {
                 status = EventP_clearBits(&gSysConfigSts_DataRDWRSynchEvent, System_StatusConfig_RDWREvnt_BIT);
                 DebugP_assert(SystemP_SUCCESS == status);


                    #ifdef Debug_VerboseSHM2
                        DebugP_log("[CIP] %s Cleared System_StatusConfig_RDWREvnt_BIT  %" PRId64 " ms\r\n",__func__,ClockP_getTimeUsec()/1000);
                    #endif
             }
        }
    }//for(;;)

}


