/**********************************************************************************************************************
*  Copyright (C), 2022-2026, SMARTLOGIC TECHNOLOGY LTD.
*  File Name: ecpri_irq.s.c
*  Create Date: 23/09/04
*  Description: eCPRI Interrupt Module Source File
*  Change History: 
*      <author>      <time>      <version>   <desc>
*    1. ShangH      23/09/04        1.0       Build this module
**********************************************************************************************************************/


/* -------------------------------------------------- <INC FILE> --------------------------------------------------- */
#include "ecpri_irq.h"


/* --------------------------------------------------- <VAR DEF> --------------------------------------------------- */
/* eCPRI send flag */
uint32_t g_ecpri_send_flag = 0; /* ECS_RFM0: 0xB7E30100(64) */
/* eCPRI send length */
uint32_t g_ecpri_send_len = 0; /* ECS_RFM0: 0xB7E30104(65) */

/* eCPRI symbol interrupt statistic */
EcpriSymIrqStats_t g_ecpri_sym_irq_stats = {0};


/* -------------------------------------------------- <FUNC DEF> --------------------------------------------------- */
/**********************************************************************************************************************
*  Function: ecpri_sym_irq_handle
*  Description: eCPRI symbol interrupt handle
*  Input: 
*    <name>                    <type>                      <desc>
*     slot_id                   uint8_t                     slot index
*     sym_id                    uint8_t                     symbol index
*  Output: none
*  Return: operation result - success or failure.
*  Others: none
**********************************************************************************************************************/
int32_t ecpri_sym_irq_handle(uint8_t slot_id, uint8_t sym_id)
{
    /* slot type */
    uint8_t slot_type = 0;
    /* antenna index */
    uint8_t ant_id = 0;
    /* start cycle */
    uint32_t start_cycle = 0;
    /* end cycle */
    uint32_t end_cycle = 0;
    /* cycle number */
    uint32_t cycle_num = 0;

    g_ecpri_sym_irq_stats.handle_times++;

    /* get eCPRI send flag */
    g_ecpri_send_flag = do_read_volatile((void *)ECPRI_DBG_ADDR0(64)); /* ECS_RFM0: 0xB7E30100(64) */
    if (0 == g_ecpri_send_flag)
    {
        g_ecpri_sym_irq_stats.handle_succ_times++;

        debug_write(ECPRI_DBG_IDX0(68), g_ecpri_sym_irq_stats.handle_times); /* ECS_RFM0: 0xB7E30110(68) */
        debug_write(ECPRI_DBG_IDX0(69), g_ecpri_sym_irq_stats.handle_succ_times); /* ECS_RFM0: 0xB7E30114(69) */

        return SUCCESS;
    }

    /* input para check */
    if ((ECPRI_SLOT_NUM <= slot_id) || (ECPRI_SYM_NUM <= sym_id))
    {
        g_ecpri_sym_irq_stats.handle_fail_times++;

        debug_write(ECPRI_DBG_IDX0(68), g_ecpri_sym_irq_stats.handle_times); /* ECS_RFM0: 0xB7E30110(68) */
        debug_write(ECPRI_DBG_IDX0(69), g_ecpri_sym_irq_stats.handle_succ_times); /* ECS_RFM0: 0xB7E30114(69) */
        debug_write(ECPRI_DBG_IDX0(70), g_ecpri_sym_irq_stats.handle_fail_times); /* ECS_RFM0: 0xB7E30118(70) */

        return ERROR;
    }

    /* calculate slot type(odd/even) */
    slot_type = slot_id % ECPRI_SLOT_TYPE;

    for (ant_id = 0; ant_id < ECPRI_ANT_NUM; ant_id++)
    {
        rdmcycle(&start_cycle);
        (void)ecpri_sym_irq_send(ant_id, slot_type, sym_id);
        rdmcycle(&end_cycle);
        cycle_num = (end_cycle + STC_CYCLE_MAX - start_cycle) % STC_CYCLE_MAX + 1;
        debug_write(ECPRI_DBG_IDX0(72 + ant_id), cycle_num); /* ECS_RFM0: 0xB7E30120(72) ~ 0xB7E3012C(75) */
    }

    g_ecpri_sym_irq_stats.handle_succ_times++;

    debug_write(ECPRI_DBG_IDX0(68), g_ecpri_sym_irq_stats.handle_times); /* ECS_RFM0: 0xB7E30110(68) */
    debug_write(ECPRI_DBG_IDX0(69), g_ecpri_sym_irq_stats.handle_succ_times); /* ECS_RFM0: 0xB7E30114(69) */
    debug_write(ECPRI_DBG_IDX0(70), g_ecpri_sym_irq_stats.handle_fail_times); /* ECS_RFM0: 0xB7E30118(70) */

    return SUCCESS;
}

/**********************************************************************************************************************
*  Function: ecpri_sym_irq_send
*  Description: eCPRI symbol interrupt send
*  Input: 
*    <name>                    <type>                      <desc>
*     ant_id                    uint8_t                     antenna index
*     slot_type                 uint8_t                     slot type
*     sym_id                    uint8_t                     symbol index
*  Output: none
*  Return: operation result - success or failure.
*  Others: none
**********************************************************************************************************************/
int32_t ecpri_sym_irq_send(uint8_t ant_id, uint8_t slot_type, uint8_t sym_id)
{
    /* config index */
    uint32_t cfg_id = 0;
    /* packet address */
    uint32_t pkt_addr = 0;
    /* packet length */
    uint32_t pkt_len = 0;

    g_ecpri_sym_irq_stats.send_times++;

    /* input para check */
    if ((ECPRI_ANT_NUM <= ant_id) || (ECPRI_SLOT_TYPE <= slot_type) || (ECPRI_SYM_NUM <= sym_id))
    {
        g_ecpri_sym_irq_stats.send_fail_times++;

        debug_write(ECPRI_DBG_IDX0(80), g_ecpri_sym_irq_stats.send_times); /* ECS_RFM0: 0xB7E30140(80) */
        debug_write(ECPRI_DBG_IDX0(82), g_ecpri_sym_irq_stats.send_fail_times); /* ECS_RFM0: 0xB7E30148(82) */

        return ERROR;
    }

    /* config index */
    cfg_id = ant_id * ECPRI_SLOT_TYPE * ECPRI_SYM_NUM + slot_type * ECPRI_SYM_NUM + sym_id;

    /* get packet address */
    pkt_addr = do_read_volatile((void *)(ECPRI_ANT_BUF_ADDR + cfg_id * ECPRI_SYM_INFO_LEN));

    /* get eCPRI send length */
    g_ecpri_send_len = do_read_volatile((void *)ECPRI_DBG_ADDR0(65)); /* ECS_RFM0: 0xB7E30104(65) */
    if (0 == g_ecpri_send_len)
    {
        /* send real length */
        pkt_len = do_read_volatile((void *)(ECPRI_ANT_BUF_ADDR + cfg_id * ECPRI_SYM_INFO_LEN + sizeof(uint32_t)));
    }
    else
    {
        /* send specify length */
        pkt_len = g_ecpri_send_len;
    }

    /* check config info */
    if ((0 == pkt_addr) || (0 == pkt_len) || (ECPRI_PKT_SIZE < pkt_len))
    {
        g_ecpri_sym_irq_stats.send_fail_times++;

        debug_write(ECPRI_DBG_IDX0(80), g_ecpri_sym_irq_stats.send_times); /* ECS_RFM0: 0xB7E30140(80) */
        debug_write(ECPRI_DBG_IDX0(82), g_ecpri_sym_irq_stats.send_fail_times); /* ECS_RFM0: 0xB7E30148(82) */

        return ERROR;
    }

    /* eCPRI CSU send packet */
    (void)ecpri_csu_send(pkt_addr, pkt_len, 0);

    g_ecpri_sym_irq_stats.send_succ_times++;

    debug_write(ECPRI_DBG_IDX0(80), g_ecpri_sym_irq_stats.send_times); /* ECS_RFM0: 0xB7E30140(80) */
    debug_write(ECPRI_DBG_IDX0(81), g_ecpri_sym_irq_stats.send_succ_times); /* ECS_RFM0: 0xB7E30144(81) */
    debug_write(ECPRI_DBG_IDX0(82), g_ecpri_sym_irq_stats.send_fail_times); /* ECS_RFM0: 0xB7E30148(82) */

    return SUCCESS;
}



