/******************************************************************
 * @file  Transmitter_Task.s.c
 * @brief:    [file description] 
 * @author: HUOHUO
 * @Date 2024年4月20日
 * COPYRIGHT NOTICE: ITTC
 * Change_date         Owner         Change_content
 * 2024年4月20日        HUOHUO       create file

*****************************************************************/
#include "transmitter_func.h"
#include "mem_def.h"

#include "common.h"
#include "log_interface.h"

#define ADDR_ALIGN(addr, val)   ((((uint32_t)(addr) + (2<<(val)) - 1)>>(val))<<(val)) 


 /*!   
 * @brief:  Transmitter任务处理流程
 * @author:  HUOHUO
 * @Date:  2024年4月20日
 */
void Transmitter_Task()
{
    //!!!DBG
    return;
    //时间统计
    g_time_start[1] = TIME_NS();
    uint16_t time0_us, time1_us;
    uint16_t time0_slot, time1_slot;  
    RUN_CNT(TRACE_TRANSMITTER_ADDR, 0);
    TRACE(TRACE_TRANSMITTER_ADDR, 3, 1);

    
    int32_t  *transmitter_malloc_dm0_ptr;
    int32_t  *transmitter_malloc_dm1_ptr;
    int32_t  *transmitter_malloc_dm2_ptr;
    int32_t  *transmitter_malloc_dm3_ptr;
    uint32_t transmitter_param_ptr;

    int32_t *transmitter_temp_dm0_ptr;
    int32_t *transmitter_temp_dm1_ptr;
    int32_t *transmitter_temp_dm2_ptr;
    int32_t *transmitter_temp_dm3_ptr;

    uint32_t transmitter_cur_slot = get_rx_nr_slot();
    uint32_t transmitter_cur_sfn = get_rx_nr_sfn();
    //STORE_EX_W((void*)addr, LOAD_EX_W((void*)addr) + 1);+1 when task be used

     //0 空间回收
    dmalloc_trim(0, APE_DM0);
    dmalloc_trim(0, APE_DM1);
    dmalloc_trim(0, APE_DM2);
    dmalloc_trim(0, APE_DM3);   

    transmitter_malloc_dm0_ptr = dmemalign_unit(0x4000, 128*1024, APE_DM0);//申请了128KiB 首地址16k对齐
    //2. DM0空间分配
    if (NULLPTR == transmitter_malloc_dm0_ptr)
    {
        TRACE(TRACE_TRANSMITTER_ADDR, 3, 0x990);
        return;
    }

    //DM0第三段，堆空间
    transmitter_temp_dm0_ptr = (int32_t *)ADDR_ALIGN(transmitter_malloc_dm0_ptr, 12);//起始地址4k对齐
    
       int rr3 = getMemoryMalloced(APE_DM3);
    TRACE(TRACE_TRANSMITTER_ADDR, 6, rr3);
    //3. DM3空间申请
    transmitter_malloc_dm3_ptr = dmemalign_unit(0x4000, 160*1024, APE_DM3);//申请了224KiB 首地址16k对齐
    //若空间申请失败，则释放已申请的空间，再退出任务
    if (NULLPTR == transmitter_malloc_dm3_ptr)
    {
        int rr = getFreeSpace(APE_DM3);
        TRACE(TRACE_TRANSMITTER_ADDR, 7, rr);
        TRACE(TRACE_TRANSMITTER_ADDR, 3, 0x993);
        //LOG_ERROR_S("DM3_fail\n");
        dfree_unit(transmitter_malloc_dm0_ptr, APE_DM0);
        return;
    }
     //DM3第二段，堆空间
    transmitter_temp_dm3_ptr = (int32_t *)ADDR_ALIGN(transmitter_malloc_dm3_ptr, 14); //起始地址16k对齐
    //4. DM1空间申请
    transmitter_malloc_dm1_ptr = dmemalign_unit(0x4000, 204800, APE_DM1);
    //若空间申请失败，则释放已申请的空间，再退出任务
    if (NULLPTR == transmitter_malloc_dm1_ptr)
    {
        //LOG_ERROR_S("DM1_fail\n");
        TRACE(TRACE_TRANSMITTER_ADDR, 3, 0x991);
        dfree_unit(transmitter_malloc_dm3_ptr, APE_DM3);
        dfree_unit(transmitter_malloc_dm0_ptr, APE_DM0);
        return;
    }
    //DM1第一段，微码配置文件
    transmitter_config_dm1_ptr = (uint32_t *)transmitter_malloc_dm1_ptr;
    //调用DMA函数，将微码配置文件搬入DM1，DDR->DM1
    if(g_transmitter_table_param.transmitter_config1_length > 0)
    {

        ape_csu_task_lookup(DMA_TAG_G2L, 1);
        ape_csu_dma_1D_G2L_ch2ch3_transfer((uint64_t)g_transmitter_table_param.transmitter_config1_ddr_ptr,
                             (uint64_t)DM_TO_CSU_ADDR(transmitter_config_dm1_ptr),
                             g_transmitter_table_param.transmitter_config1_length,
                             DMA_TAG_G2L,
                             0);
    }
    //DM1第二段，堆空间
    transmitter_temp_dm1_ptr = (int32_t *)ADDR_ALIGN(transmitter_config_dm1_ptr + \
        g_transmitter_table_param.transmitter_config1_length, 12); //起始地址4k对齐
    //5. DM2空间申请

    transmitter_malloc_dm2_ptr = dmemalign_unit(0x4000, 128*1024, APE_DM2);//申请了224KiB 首地址16k对齐
    //若空间申请失败，释放已申请的空间，再退出任务
    if (NULLPTR == transmitter_malloc_dm2_ptr)
    {
        //int rr = getFreeSpace(APE_DM2);
        //(TRACE_TRANSMITTER_ADDR, 7, rr);
        //LOG_ERROR_S("DM2_fail\n");
        TRACE(TRACE_TRANSMITTER_ADDR, 3, 0x992);
        dfree_unit(transmitter_malloc_dm3_ptr, APE_DM3);
        dfree_unit(transmitter_malloc_dm0_ptr, APE_DM0);
        dfree_unit(transmitter_malloc_dm1_ptr, APE_DM1);
        return;
    }

    //DM2第二段，堆空间
    transmitter_temp_dm2_ptr = (int32_t *)ADDR_ALIGN(transmitter_malloc_dm2_ptr, 14); //起始地址16k对齐
    
    TRACE(TRACE_TRANSMITTER_ADDR, 3, 2);
    time1_us = Time_offset(1);
    
    TRACE_MAX(TRACE_TRANSMITTER_ADDR, 4, time1_us);
    time0_slot = time1_slot;
    time0_us = time1_us;
    //6. 计算流程
    Transmitter_Proc(
        (uint32_t*)transmitter_param_ptr,
        transmitter_temp_dm0_ptr,
        transmitter_temp_dm1_ptr,
        transmitter_temp_dm2_ptr,
        transmitter_temp_dm3_ptr,
        transmitter_cur_slot,
        transmitter_cur_sfn
    );

    time1_us = Time_offset(1);
    TRACE_MAX(TRACE_TRANSMITTER_ADDR, 5,  time1_us - time0_us);
    time0_us = time1_us;


    //7. 内存释放
    int result00,result01;
    int result10,result11;
    int result20, result21;
    int result30,result31;
    result20 = getMemoryMalloced(APE_DM2);
    dfree_unit(transmitter_malloc_dm2_ptr, APE_DM2);
    result21 = getMemoryMalloced(APE_DM2);

    result10 = getMemoryMalloced(APE_DM1);
    dfree_unit(transmitter_malloc_dm1_ptr, APE_DM1);
    result11 = getMemoryMalloced(APE_DM1);

    result30 = getMemoryMalloced(APE_DM3);
    dfree_unit(transmitter_malloc_dm3_ptr, APE_DM3);
    result31 = getMemoryMalloced(APE_DM3);

    result00 = getMemoryMalloced(APE_DM0);
    dfree_unit(transmitter_malloc_dm0_ptr, APE_DM0);
    result01 = getMemoryMalloced(APE_DM0);

    TRACE(TRACE_TRANSMITTER_ADDR, 3, 1024);
    RUN_CNT(TRACE_TRANSMITTER_ADDR, 1);
    TRACE_MAX(TRACE_TRANSMITTER_ADDR, 2, Time_offset(1) );
    //LOG_ERROR_S("DM0:%d:%d, DM1:%d:%d,DM2:%d:%d,DM3:%d:%d\n",result00,result01,result10,result11,result20,result21,result30,result31);
    return;
}
