// +FHDR------------------------------------------------------------
//                 Copyright (c) 2022 SmartLogic.
//                       ALL RIGHTS RESERVED
// -----------------------------------------------------------------
// Filename      : main.c
// Author        : lishuang.xie
// Created On    : 2023-09-18
// Last Modified :
// -----------------------------------------------------------------
// Description:
//
// rfic function
//
// -FHDR------------------------------------------------------------

#define _GNU_SOURCE
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include "../inc/typedef.h"
#include "../inc/ucp_api_rfic.h"
#include "../inc/xzJSON.h"

#define RFIC_CFG_FILE_PATH    "/lib/firmware/resources/ucp_rfic_cfg.json"
#define RFIC_SEM_KEY          0x1027

typedef struct ucp_rfic_cfg_info
{
    uint64_t txLo;
    uint64_t rxLo;
    uint64_t auxLo;
    uint16_t initAtt;
    uint16_t initGain;
    uint32_t u32padding;
    uint64_t sampleRate;
    uint64_t bw;
    uint16_t antNumb;
    uint16_t enFdd;
    uint16_t enOrx;
    uint16_t en204C;
    uint16_t enUcpLog;
    uint16_t u16padding;
    uint32_t u32padding2;
    ucp_rfic_calPara_t st_rfic_calPara;

}ucp_rfic_cfg_info_t;

#if 1
extern xzJSON* ucp_jsonLoad (const char *fileName);
extern xzJSON* xzJSON_GetObjectItem(const xzJSON * const object, const char * const string);


ucp_rfic_cfg_info_t rfic_get_cfg_info()
{
    ucp_rfic_cfg_info_t st_rfic_cfg;
    xzJSON *root   = NULL;
    xzJSON *item   = NULL;
    xzJSON *config = NULL;

    root = ucp_jsonLoad(RFIC_CFG_FILE_PATH);
    if (((xzJSON*)NULL) == root)
    {
        printf("rfic_get_cfg_info: load file error!\r\n");
        exit(1);
    }

    item = xzJSON_GetObjectItem(root, "common");
    config = xzJSON_GetObjectItem(item, "txLo");
    st_rfic_cfg.txLo  = config->valuedouble;
    config = xzJSON_GetObjectItem(item, "rxLo");
    st_rfic_cfg.rxLo  = config->valuedouble;
    config = xzJSON_GetObjectItem(item, "auxLo");
    st_rfic_cfg.auxLo = config->valuedouble;
    config = xzJSON_GetObjectItem(item, "initAtt");
    st_rfic_cfg.initAtt  = config->valueint;
    config = xzJSON_GetObjectItem(item, "initGain");
    st_rfic_cfg.initGain = config->valueint;

    item = xzJSON_GetObjectItem(root, "para");
    config = xzJSON_GetObjectItem(item, "sampleRate");
    st_rfic_cfg.sampleRate = config->valuedouble;
    config = xzJSON_GetObjectItem(item, "bw");
    st_rfic_cfg.bw         = config->valuedouble;
    config = xzJSON_GetObjectItem(item, "antNumb");
    st_rfic_cfg.antNumb    = config->valueint;
    config = xzJSON_GetObjectItem(item, "enFdd");
    st_rfic_cfg.enFdd      = config->valueint;
    config = xzJSON_GetObjectItem(item, "enOrx");
    st_rfic_cfg.enOrx      = config->valueint;
    config = xzJSON_GetObjectItem(item, "en204C");
    st_rfic_cfg.en204C     = config->valueint;
    config = xzJSON_GetObjectItem(item, "enUcpLog");
    st_rfic_cfg.enUcpLog   = config->valueint;

    config = xzJSON_GetObjectItem(item, "calOrxGainIndex");
    st_rfic_cfg.st_rfic_calPara.calOrxGainIndex = config->valueint;

    item = xzJSON_GetObjectItem(item, "calChAttPara");
    config = xzJSON_GetObjectItem(item, "ch1");
    st_rfic_cfg.st_rfic_calPara.calChAttPara[0] = config->valueint;
    config = xzJSON_GetObjectItem(item, "ch2");
    st_rfic_cfg.st_rfic_calPara.calChAttPara[1] = config->valueint;
    config = xzJSON_GetObjectItem(item, "ch3");
    st_rfic_cfg.st_rfic_calPara.calChAttPara[2] = config->valueint;
    config = xzJSON_GetObjectItem(item, "ch4");
    st_rfic_cfg.st_rfic_calPara.calChAttPara[3] = config->valueint;

    xzJSON_Delete(root);

    return st_rfic_cfg;
}
#endif


int32_t gi32_rfic_sem = 0;

int32_t rfic_sem_create(void)
{
    int32_t i32_ret = 0;

    /* create sem */
    gi32_rfic_sem = semget((key_t)RFIC_SEM_KEY, 1, IPC_CREAT);
    if (-1 == gi32_rfic_sem)
    {
        printf("rfic_sem_create semget error!\r\n");
        return -1;
    }

    /* set value */
    i32_ret = semctl(gi32_rfic_sem, 0, SETVAL, 0);
    if (-1 == i32_ret)
    {
        printf("rfic_sem_create semctrl error!\r\n");
        return -2;
    }
    return 0;
}

int32_t rfic_sem_post(int32_t sem_id)
{
    int32_t i32_ret = 0;
    struct sembuf st_sem_buf;
    memset(&st_sem_buf, 0, sizeof(st_sem_buf));
    st_sem_buf.sem_num = 0;
    st_sem_buf.sem_op  = 1;
    st_sem_buf.sem_flg = SEM_UNDO;

    i32_ret = semop(sem_id, &st_sem_buf, 1);
    if (-1 == i32_ret)
    {
        printf("rfic_sem_post semop return error!\r\n");
        return -1;
    } 

    return 0;
}

int32_t main(int32_t argc, char* argvp[])
{
    ucp_rfic_cfg_info_t st_rfic_cfg_info;

    /* create sem */
    int32_t i32_ret = rfic_sem_create();
    if (0 != i32_ret)
    {
        printf("rfic_sem_create return %d\r\n", i32_ret);
        return -1;
    }

#if 1
    st_rfic_cfg_info = rfic_get_cfg_info();
    printf("common: txLo:%ld, rxLo:%ld, auxLo:%ld, initAtt:%d, initGain:%d\r\n", 
            st_rfic_cfg_info.txLo,
            st_rfic_cfg_info.rxLo,
            st_rfic_cfg_info.auxLo,
            st_rfic_cfg_info.initAtt,
            st_rfic_cfg_info.initGain);

    printf("para: sampleRate:%ld, bw:%ld, antNumb:%d, enFdd:%d, enOrx:%d, en204C:%d, enUcpLog:%d\r\n", 
            st_rfic_cfg_info.sampleRate,
            st_rfic_cfg_info.bw,
            st_rfic_cfg_info.antNumb,
            st_rfic_cfg_info.enFdd,
            st_rfic_cfg_info.enOrx,
            st_rfic_cfg_info.en204C,
            st_rfic_cfg_info.enUcpLog);

    printf("GainIndex:%d, calChAttPara.ch1:%d, ch2:%d, ch3:%d, ch4:%d\r\n",
            st_rfic_cfg_info.st_rfic_calPara.calOrxGainIndex,
            st_rfic_cfg_info.st_rfic_calPara.calChAttPara[0],
            st_rfic_cfg_info.st_rfic_calPara.calChAttPara[1],
            st_rfic_cfg_info.st_rfic_calPara.calChAttPara[2],
            st_rfic_cfg_info.st_rfic_calPara.calChAttPara[3]);

#endif
    /* call jesd init function */
    UCP_API_RFIC_CellInit(st_rfic_cfg_info.sampleRate, 
                          st_rfic_cfg_info.bw,
                          st_rfic_cfg_info.antNumb,
                          st_rfic_cfg_info.enFdd,
                          st_rfic_cfg_info.enOrx,
                          st_rfic_cfg_info.en204C,
                          st_rfic_cfg_info.enUcpLog);

    UCP_API_RFIC_CellSetup(st_rfic_cfg_info.txLo, 
                           st_rfic_cfg_info.rxLo, 
                           st_rfic_cfg_info.initAtt, 
                           st_rfic_cfg_info.initGain,
                           st_rfic_cfg_info.auxLo,
                           st_rfic_cfg_info.enOrx,
                           st_rfic_cfg_info.st_rfic_calPara);
    //UCP_API_RFIC_CellSetup(2575770000u, 2575770000u, 0);

    /* post sem  */
    i32_ret = rfic_sem_post(gi32_rfic_sem);
    if (0 != i32_ret)
    {
        printf("rfic_sem_post return %d\r\n", i32_ret);
        return -2;
    }

    return 0;
}


