/**
 * @file           shm_api.c
 * @brief          共享内存接口文件
 * @author         lch (lch_work@foxmail.com)
 * @version        1.0
 * @date           20250917
 * 
 * @copyright Copyright (c) 2025 by OLE, All Rights Reserved.
 * 
 * @par 修改日志:
 * <table>
 * <tr><th>Date        <th>Version         <th>Author          <th>Description
 * <tr><td>20250917    <td>1.0             <td>lch             <td>内容
 * </table>
 */


/***** 宏定义 *****/

#ifndef DEF_SHM_API_H
#define DEF_SHM_API_H

#define MAX_SHMEM_RD_LEN	(CONFIG_SHARE_MEM_LENGTH / 2)
#define MAX_SHMEM_WR_LEN	(CONFIG_SHARE_MEM_LENGTH / 2)
#define MAX_SHMEM_RD_DATA_LEN	(MAX_SHMEM_RD_LEN)
#define MAX_SHMEM_WR_DATA_LEN	(MAX_SHMEM_WR_LEN)

/* 内存地址 */
/* linux核写 RV核读 */
#define SHM_ADDR_R_MACHINETYPE          0x00000000 /* 装置类型 */
#define SHM_ADDR_R_DI_ASTIME            0x00001000 /* 开入防抖时间 */
#define SHM_ADDR_R_TIMESTAMP            0x00002000 /* ms时间戳 */
#define SHM_ADDR_R_MACHINEPARAM         0x00003000 /* 参数数据 */

/* linux核读 RV核写 */
#define SHM_ADDR_W_DI                   0x00000000 /* 开入量数据 */
#define SHM_ADDR_W_FREQ                 0x00001000 /* 频率 */
#define SHM_ADDR_W_U_ADC_1              0x00020000 /* 第一片ADC采样数据区 */
#define SHM_ADDR_W_U_ADC_2              0x00040000 /* 第二片ADC采样数据区 */
#define SHM_ADDR_W_U_ADC_3              0x00060000 /* 第三片ADC采样数据区 */
#define SHM_ADDR_W_U_ADC_4              0x00080000 /* 第四片ADC采样数据区 */
#define SHM_ADDR_W_U_ADC_5              0x000A0000 /* 第五片ADC采样数据区 */
#define SHM_ADDR_W_FLAG                 0x000C0000 /* 标志数据 */

#ifndef DI_MAX
#define DI_MAX  (31)
#endif

#ifndef ADC_SAMPLEING_RATE  /* ADC采样率 0 : 6400(156.25us) 1 : 12800(78.125us)  */
#define ADC_SAMPLEING_RATE 1
#endif

#define ADC_HARDWARE_NUM    5  /* ADC片数 先按最多的5个来 */
#define ADC_CHANNEL         16 /* ADC采样的通道数 */

#if (0 == ADC_SAMPLEING_RATE)

#define ADC_SAMPLE_PER_CYCLE 128 /* 录波每周采样点数 */
/* 每个ADC通道缓存的采样点数 理论上不会溢出 64  */
#define TC_ADC_DOTS_PER_CHANNEL (ADC_SAMPLE_PER_CYCLE / 2)

#else /* ADC_SAMPLEING_RATE */

#define ADC_SAMPLE_PER_CYCLE 256 /* 录波每周采样点数 */
/* 每个ADC通道缓存的采样点数 理论上不会溢出 96  */
#define TC_ADC_DOTS_PER_CHANNEL ((ADC_SAMPLE_PER_CYCLE / 4) + ((ADC_SAMPLE_PER_CYCLE / 8)))

#endif /* ADC_SAMPLEING_RATE */

#define ADC_SAMPLE_UPDATA (ADC_SAMPLE_PER_CYCLE / 4) /* 录波更新点数 */

/***** 头文件 *****/

/*****  枚举  *****/

enum e_shm_type
{
    e_shm_machinetype = 0,
    e_shm_di_astime,
    e_shm_timestamp,
    
    e_shm_type_max,
};

/***** 结构体 *****/

/****************************** A核写, R核读 ******************************/

/* 装置类型 */
struct t_shmdata_machine_type
{
    uint16_t us_updata;       /* 数据更新标志 */
    uint16_t us_op;           /* 操作标志 */
    uint16_t us_op_bk;        /* 操作标志备份 */
    uint16_t us_machine_type; /* 数据 */
    uint16_t us_crc;          /* crc 应用不用处理 底层接口处理 */
};

/* 开入防抖时间 */
struct t_shmdata_di_astime
{
    uint16_t us_updata;      /* 数据更新标志 */
    uint16_t us_op;          /* 操作标志 */
    uint16_t us_op_bk;       /* 操作标志备份 */
    uint16_t us_as_time[32]; /* 数据 */
    uint16_t us_crc;         /* crc 应用不用处理 底层接口处理 */
};

/* ms时间戳 */
struct t_shmdata_timestamp
{
    uint16_t us_updata;      /* 数据更新标志 */
    uint16_t us_op;          /* 操作标志 */
    uint16_t us_op_bk;       /* 操作标志备份 */
    uint64_t ull_timestamp;  /* 数据 */
    uint16_t us_crc;         /* crc 应用不用处理 底层接口处理 */
} __attribute__ ((packed)); /* 大小16个字节 */

/****************************** A核读, R核写 ******************************/

/* 开入量 */

struct t_sd_di_status
{
    uint8_t uc_state;       // 开入量状态
    uint64_t ull_timestamp; // 时间戳
};

struct t_shmdata_di
{
    uint16_t us_updata;               /* 数据更新标志 */
    uint16_t us_op;                   /* 操作标志 */
    uint16_t us_op_bk;                /* 操作标志备份 */
    struct t_sd_di_status di[DI_MAX]; /* 数据 */
    uint16_t us_crc;                  /* crc 应用不用处理 底层接口处理 */
}__attribute__ ((packed)); /* 大小504个字节 */

/* 频率 */
struct t_shmdata_freq
{
    uint16_t us_updata; /* 数据更新标志 */
    uint16_t us_op;     /* 操作标志 */
    uint16_t us_op_bk;  /* 操作标志备份 */
    uint16_t us_freq[2];/*放大1000倍*/
    uint16_t us_crc;    /* crc 应用不用处理 底层接口处理 */
};

/**< 采样点结构体 */
struct t_sampledata_mc
{
    uint16_t us_sample_idx;       /* 采样索引下标 */
    uint16_t us_ft_idx;           /* 频率变化下标 */
    uint16_t us_xdl_idx;          /* 小电流突变下标 */
    uint16_t usa_sample_dots[ADC_CHANNEL][TC_ADC_DOTS_PER_CHANNEL];
};

/* 采样数据 */
struct t_shmdata_adc
{
    uint16_t us_updata;          /* 数据更新标志 */
    uint16_t us_op;              /* 操作标志 */
    uint16_t us_op_bk;           /* 操作标志备份 */
    struct t_sampledata_mc data; /* 数据 */
    uint16_t us_crc;             /* crc 应用不用处理 底层接口处理 */
}; /* 大小3086个字节 */

/* 标志数据 */
struct t_shmdata_flag
{   
    uint16_t us_updata;         /* 数据更新标志 */
    uint16_t us_op;             /* 操作标志 */
    uint16_t us_op_bk;          /* 操作标志备份 */
    uint16_t us_cfg_adc_err;    /* ADC初始化错误 */
    uint16_t us_crc;            /* crc 应用不用处理 底层接口处理 */
};  /* 大小10个字节 */

struct t_device_shm
{
    int (*init)             (void);
    int (*read)             (uint32_t _ul_addr, uint32_t _ul_len, uint8_t *_puc_data_out, uint32_t _uc_data_out_size);
    int (*write)            (uint32_t _ul_addr, uint8_t *_puc_data, uint32_t _ul_len);
    int (*pack_read)        (uint32_t _ul_addr, uint32_t _ul_len, uint8_t *_puc_data_out, uint32_t _uc_data_out_size);
    int (*pack_write)       (uint32_t _ul_addr, uint8_t *_puc_data, uint32_t _ul_len);
    int (*scan_data)        (enum e_shm_type _e_type);
};

/***** 变量对外声明 *****/

/**
 * @brief       共享内存结构体
 * 
 * @note        gt_shm.init 初始化
 * @note        gt_shm.read 从共享内存读取数据
 *        -     {uint32_t} _ul_addr 读取共享内存的地址
 *        -     {uint32_t} _ul_len 需要读取的数据长度
 *        -     {uint8_t *} _puc_data_out 输出buf
 *        -     {uint32_t} _uc_data_out_size 输出buf的长度
 *        -     成功返回读取数据的长度, 失败返回-1
 * 
 * @note        gt_shm.write 往共享内存写入数据
 *        -     {uint32_t} _ul_addr 共享内存的地址
 *        -     {uint8_t *} _puc_data 需要写入的数据
 *        -     {uint32_t} _ul_len 需要写入的数据长度
 *        -     成功返回读取数据的长度, 失败返回-1
 * 
 * @note        gt_shm.pack_read 从共享内存读取数据 带读写标志
 *        -     {uint32_t} _ul_addr 读取共享内存的地址
 *        -     {uint32_t} _ul_len 需要读取的数据长度
 *        -     {uint8_t *} _puc_data_out 输出buf
 *        -     {uint32_t} _uc_data_out_size 输出buf的长度
 *        -     成功返回读取数据的长度, 失败返回-1
 * 
 * @note        gt_shm.pack_write 往共享内存写入数据 带读写标志
 *        -     {uint32_t} _ul_addr 共享内存的地址
 *        -     {uint8_t *} _puc_data 需要写入的数据
 *        -     {uint32_t} _ul_len 需要写入的数据长度
 *        -     成功返回读取数据的长度, 失败返回-1
 * 
 * @note        gt_shm.scan_data 扫描共享内存数据更新
 *        -     {enum e_shm_type} _e_type 共享内存的类型描述
 *        -     有数据更新返回1
 */
extern struct t_device_shm gt_shm;

/***** 函数对外声明 *****/

#endif /* end of file */