#include <stdlib.h>
#include <string.h>
#include "spu_shell.h"
#include "ucp_printf.h"
#include "spu_log.h"
#include "ucp_drv_common.h"
#include "ucp_utility.h"
#include "typedef.h"
#include "phy_para.h"

OSP_CMD_RTN gastCmdRtnTblExt[MAX_EXT_CMD_NUM];
OSP_CMD_EXT gastCmdExt[MAX_EXT_CMD_NUM];

int ospCmdRtnExtNum =0;
uint32_t gu32_osp_shell_task_cnt = 0;
uint32_t gu32_osp_shell_task_rev = 0;
uint32_t g_ulsendcount = 0;
char seps[]=" ,\t\n\"";
uint32_t g_core_id = 0;

uint32_t SHELL_CMD_NUM_EXT = 0;
static char szPrompt[] = {"-> "};

static T_WaitKeyState waitKeyState = WKS_WAIT;
static char szCmdHistory[MAX_CMD_HISTORY][MAX_CMD_LEN];
static char szCmdNow[MAX_CMD_LEN] = {0};

static unsigned long nCmdIndex        = 0;
static unsigned long nCmdCursor       = 0;
static unsigned long nCmdInputCount  = 0;
static unsigned long nCmdInputCursor = 0;

static uint32_t argval[10]  =  {0};
static char argchar[10][32] = {0};
static char shellOut[64]     ={0};


OSP_CMD_RTN ospCmdRtnTbl[] =
{
    //{"level_ape", (OSP_FUNCPTR)spu_shell_wrapper, (OSP_FUNCPTR)spu_set_log_level},
    {"recmd_ape", (OSP_FUNCPTR)spu_shell_wrapper, (OSP_FUNCPTR)spu_reget_cmd},
    {"intr_ape",  (OSP_FUNCPTR)spu_shell_wrapper, (OSP_FUNCPTR)spu_csu_int_cnt},
    //{"csu_stop_ape", (OSP_FUNCPTR)spu_shell_wrapper,(OSP_FUNCPTR)spu_csu_stop_cfg},
    //{"i_ape", (OSP_FUNCPTR)osp_show_task_info, NULL},		
    //{"re_ape", (OSP_FUNCPTR)spu_insert_cmd_ext_test, NULL},
};

int  SHELL_CMD_NUM = SHELL_NELEMENTS(ospCmdRtnTbl);
int  cmdMatched = 0;
char cmdMatchBuf[SHELL_NELEMENTS(ospCmdRtnTbl)][MAX_CMD_LEN + 10] = {0};
char cmdShowBuf[MAX_CMD_LEN*SHELL_NELEMENTS(ospCmdRtnTbl)] = {0};
static int nCmdField;
static int maxCmdField=10;
static char *g_parg[32]={0};


void *spu_find_sym(char * addr)
{
    return addr;
}

int spu_isprint( int ch )
{

    return (unsigned int)(ch - ' ') < 127u - ' ';

}

int spu_isdigit( int ch )
{

    return (unsigned int)(ch - '0') < 10u;

}
static void write(int fd, char *buf, int len)
{
    int i;
    for(i=0; i<len; i++)
        osp_putc(buf[i]);
}


int spu_insert_cmd(char *name,  OSP_FUNCPTR pfunc)
{
    return 0;
}

void spu_insert_cmd_ext(char *name, OSP_FUNCPTR pfunc, char *desc, uint32_t argnum)
{
    uint32_t num      = 0;
    uint32_t i        = 0;
    OSP_CMD_RTN *tlb  = NULL;
    
    //int32_t core_id = get_core_id();
    //debug_write(DBG_DDR_COMMON_IDX(core_id, 130), argnum);/*0xb7e00208 参数个数地址*/

    if ((name == NULL) || pfunc == NULL)
    {    
        UCP_PRINT_EMPTY("osp_insert_cmd_ext name:%p pfunc:%p\r\n", name, pfunc);
        return;
    }

    for (i = 0; i < MAX_EXT_CMD_NUM; i++)
    {
        if (strcmp(gastCmdRtnTblExt[i].cmd, name) == 0)
        {
            UCP_PRINT_EMPTY("osp_insert_cmd_ext i:%u cmd:%s has exist name:%s\r\n", i, gastCmdRtnTblExt[i].cmd, name);
            return;
        }
    }
    
    tlb = gastCmdRtnTblExt;
    num = SHELL_CMD_NUM_EXT;
    if(num >= MAX_EXT_CMD_NUM)
    {
        UCP_PRINT_EMPTY("osp_insert_cmd_ext num:%u beyond MAX_EXT_CMD_NUM:%d\r\n", num, MAX_EXT_CMD_NUM);
        return;
    }

    memcpy_ucp(tlb[num].cmd, name, strlen(name) + 1);
    memcpy_ucp(tlb[num].descption, desc, strlen(desc) + 1);
    tlb[num].wrapper = (OSP_FUNCPTR)spu_shell_wrapper;
    //memcpy_ucp(tlb[num].wrapper, (OSP_FUNCPTR)spu_shell_wrapper, sizeof(OSP_FUNCPTR));
    //memcpy_ucp(tlb[num].routine, pfunc, sizeof(OSP_FUNCPTR));
    tlb[num].routine = pfunc;
    tlb[num].argnum          = argnum;

    memcpy_ucp(gastCmdExt[num].cmd, name, strlen(name) + 1);
    gastCmdExt[num].argnum    = argnum;

    SHELL_CMD_NUM_EXT++; 
    gastCmdExt[num].num    = SHELL_CMD_NUM_EXT;

    UCP_PRINT_EMPTY("osp_insert_cmd_ext name:%s num:%u argnum:%u\r\n", gastCmdExt[num].cmd, gastCmdExt[num].num, tlb[num].argnum);

    //debug_write(DBG_DDR_COMMON_IDX(core_id, 131), SHELL_CMD_NUM_EXT);

    spu_shellinfo_to_arm((char *)&gastCmdExt[num], sizeof(OSP_CMD_EXT), UCP4008_OSP_SHELL_REG);
    
    return;

}

void spu_reget_cmd()
{
    uint32_t i        = 0;

    for (i = 0; i < SHELL_CMD_NUM_EXT; i++)
    {        
        UCP_PRINT_LOG("spu_reget_cmd i:%u cmd:%s\r\n", i, gastCmdRtnTblExt[i].cmd);        
        spu_shellinfo_to_arm((char *)&gastCmdExt[i], sizeof(OSP_CMD_EXT), UCP4008_OSP_SHELL_REG);
    }

    return;

}

void spu_set_log_level(uint8_t ucLevel)
{    
    if(ucLevel > LOG_TICK)
    {
        #ifdef LOG_SWITCH
        UCP_PRINT_ERROR("spu_set_log_level ucLevel:%u\n", ucLevel);
        #endif
        return;
    }
    
    //debug_write(DBG_DDR_COMMON_IDX(get_core_id(), 159), ucLevel);
    spu_log_init(ucLevel);

    return;
}


int spu_shell_init(void)
{
    g_core_id = get_core_id();

    spu_insert_cmd_ext("csu_ape", (OSP_FUNCPTR)spu_csu_stop_cfg, "cfg csu info", 2);
    spu_insert_cmd_ext("level_ape", (OSP_FUNCPTR)spu_log_level_set, "cfg ape print level", 1);
    spu_insert_cmd_ext("slevel_ape", (OSP_FUNCPTR)spu_log_level_get, "get ape print level", 0);

    return 0;
}


/******************************************************************************
* set_out_str - print string to console
* input:
*    out : output string
* return
*    none
*/

void set_out_str(char *out)
{
	//UCP_PRINT_LOG("%s", out);
}


/******************************************************************************
* set_prompt - set prompt string to console
* input:
*    none
* return
*    none
*/

void set_prompt()
{
    UCP_PRINT_LOG("%s", szPrompt);
}

int spu_shell_symo(char **arg, int len)
{
    int i;
    OSP_FUNCPTR func;

    unsigned long func_ret;

    for(i = 0; i < len; i++)
    {
        if((arg[i][0] == '0') && ((arg[i][1] == 'x') || (arg[i][1] == 'X')))
        {
            argval[i] = (uint32_t)strtoul(arg[i], (char **)NULL, 16);
        }
        else if(spu_isdigit(arg[i][0]))
        {
            argval[i] = (uint32_t)strtoul(arg[i], (char **)NULL, 10);
        }
        else
        {
            return -1;
        }
    }

    func = spu_find_sym((char *)argval[0]);
       
    if(func)
    {
        func_ret = func(argval[1], argval[2], argval[3], argval[4], 
            argval[5], argval[6], argval[7], argval[8], argval[9]);
        //set_out_str(shellOut);
        /*结果发送到arm*/
       // osp_msg_transfer_send(UCP4008_OSP_SHELL, shellOut, sizeof(shellOut));

        return 0;
    }

    return -1;
}



int spu_shell_wrapper(char **arg, int len, OSP_FUNCPTR func)
{
    int i;
    int ret;

    for(i = 0; i < len; i++)
    {
        if((arg[i][0] == '0') && ((arg[i][1] == 'x') || (arg[i][1] == 'X')))
        {
        
            argval[i] = strtoul(arg[i], (char **)NULL, 16);
        }
        else if(spu_isdigit(arg[i][0]))
        {
            argval[i] = strtoul(arg[i], (char **)NULL, 10);
        }
        else
        {
            strcpy(argchar[i], arg[i]);
            argval[i] = (long)argchar[i];
        }
    }

    ret = func(argval[0], argval[1], argval[2], argval[3], argval[4], 
        argval[5], argval[6], argval[7], argval[8], argval[9]);

    return ret;
}


/******************************************************************************
* get_full_cmd_match - get matched command name list
* input:
*    pCmd : the prefix of a command
* return
*    none
*/

int get_full_cmd_match( char* pCmd )
{
    int index;
    char* pMatch;

    for ( index = 0; index < SHELL_NELEMENTS( ospCmdRtnTbl ); index++ )
    {
        pMatch = strstr( ospCmdRtnTbl[index].cmd, pCmd );
        if ( ( pMatch != NULL ) && ( pMatch == ospCmdRtnTbl[index].cmd ) )
        {
            strcpy( cmdMatchBuf[cmdMatched], ospCmdRtnTbl[index].cmd );
            cmdMatched++;
        }
    }
    return cmdMatched;
}


/******************************************************************************
* get_cmd_arg - split command to params,then save to array arg
* input:
*    cmd : pointer to command
* return
*    params number
*/
int get_cmd_arg(char *cmd)
{
    char *token;

    nCmdField = 0;

    token = strtok(cmd, seps);    

    while (token != NULL)
    {   
        if (nCmdField >= maxCmdField)
        {
            return -1;
        }
        g_parg[nCmdField] = token;
        token = strtok(NULL, seps);
        nCmdField++;
    }

    return nCmdField;
}


int match_cmd(int num,  OSP_CMD_RTN*tlb)
{
    int i;
//    int ret;
    if((0 == num) || (NULL == tlb))
        return -1;

    for (i = 0; i < num; i++)
    {
        if (strcmp(tlb[i].cmd, g_parg[0]) == 0)
        {        
            //ret = (*tlb[i].wrapper)(&g_parg[1], nCmdField-1, tlb[i].routine);
            spu_shell_wrapper(&g_parg[1], nCmdField-1, tlb[i].routine);
            set_out_str(shellOut);
            return (0);
        }
    }
    return -1;
}
/****************************************************************************** 
* exec_cmd - execute command
* input:
*    none
* return
*    OSP_OK,or
*    OSP_ERROR(fail)
*/
int exec_cmd(void)
{
    int ret;
    int num;
    OSP_CMD_RTN* tlb;
    
    if (nCmdField > 0)
    {
        num = SHELL_CMD_NUM;
        tlb = ospCmdRtnTbl;
        ret = match_cmd(num, tlb);
        if(!ret)
        {
            return ret;
        }
        
        num = SHELL_CMD_NUM_EXT;
        tlb = gastCmdRtnTblExt;
        ret = match_cmd(num, tlb);
        if(!ret)
        {
            return ret;
        }
        
        ret = spu_shell_symo(&g_parg[0], nCmdField);

        return ret;

    }
    
    return (-1);
}

/******************************************************************************
* shell_write_bs - delete a character of command line
* input:
*    none
* return
*    none
*/
void shell_write_bs()
{
    char szTemp[3];
    szTemp[0] = '\b';
    szTemp[1] = ' ';
    szTemp[2] = '\b';
    write(STDOUT_FILENO,szTemp,3);
}

/******************************************************************************
* shell_deal_input - handle keypress
* input:
*    input: input key code
* return
*    none
*/

void shell_deal_input(char input)
{
    if(nCmdInputCount == MAX_CMD_LEN)
        return;

    if(nCmdInputCursor < nCmdInputCount)
    {
        char szTemp[MAX_CMD_LEN] = {0};
        char* pCmd = szCmdNow;
        int nBackCount = nCmdInputCount-nCmdInputCursor;
        szTemp[0] = input;
        memcpy(&szTemp[1],&pCmd[nCmdInputCursor],nBackCount);
        write(STDOUT_FILENO,szTemp,nBackCount+1);
        memcpy(&pCmd[nCmdInputCursor],&szTemp,nBackCount+1);

        memset(szTemp,'\b',nBackCount);
        write(STDOUT_FILENO,szTemp,nBackCount);
    }
    else
    {
        write(STDOUT_FILENO,&input,1);
        szCmdNow[nCmdInputCount] = input;
    }

    nCmdInputCursor++;
    nCmdInputCount++;
}

/******************************************************************************
* shell_deal_backspace - handle key 'Backspace'
* input:
*    none
* return
*    none
*/
void shell_deal_backspace()
{
    if(nCmdInputCursor > 0)
    {
        if(nCmdInputCursor == nCmdInputCount) //cursor at the end
            shell_write_bs();
        else
        {
            char szTemp[MAX_CMD_LEN] = {0};
            char* pCmd = szCmdNow;
            int nBackCount = nCmdInputCount-nCmdInputCursor;
            szTemp[0] = '\b';
            memcpy(&szTemp[1],&pCmd[nCmdInputCursor],nBackCount);
            szTemp[nBackCount+1] = ' ';
            write(STDOUT_FILENO,szTemp,nBackCount+2);
            memcpy(&pCmd[nCmdInputCursor-1],&szTemp[1],nBackCount);

            memset(szTemp,'\b',nBackCount+1);
            write(STDOUT_FILENO,szTemp,nBackCount+1);
        }
        nCmdInputCount --;
        nCmdInputCursor--;
    }
}

/******************************************************************************
* shell_deal_delete - handle key 'Delete'
* input:
*    none
* return
*    none
*/
void shell_deal_delete()
{
    if(nCmdInputCursor < nCmdInputCount)
    {
        char szTemp[MAX_CMD_LEN] = {0};
        char* pCmd = szCmdNow;

        int nBackCount = nCmdInputCount-nCmdInputCursor-1;
        memcpy(szTemp,&pCmd[nCmdInputCursor+1],nBackCount);
        szTemp[nBackCount] = ' ';
        write(STDOUT_FILENO,szTemp,nBackCount+1);
        memcpy(&pCmd[nCmdInputCursor],szTemp,nBackCount);

        memset(szTemp,'\b',nBackCount+1);
        write(STDOUT_FILENO,szTemp,nBackCount+1);
        nCmdInputCount--;
    }
}

/******************************************************************************
* shell_deal_double_esc - clear command line
* input:
*    none
* return
*    none
*/

void shell_deal_double_esc()
{
    if(nCmdInputCount > 0)
    {
        char* pCmd = szCmdNow;

        //move to end
        while(nCmdInputCursor < nCmdInputCount)
        {
            write(STDOUT_FILENO,&pCmd[nCmdInputCursor],1);
            nCmdInputCursor++;
        }

        //clear all inputs
        int i=0;
        for(i=0;i<nCmdInputCount;i++)
            shell_write_bs();
        nCmdInputCount = 0;
        nCmdInputCursor = 0;
    }
}

/******************************************************************************
* shell_deal_up_key - handle key 'up'
* input:
*    none
* return
*    none
*/

void shell_deal_up_key()
{
    if(nCmdCursor == 0)
        return;

    nCmdCursor --;

    //clear all inputs
    shell_deal_double_esc();

    char* pCmdHistory = &szCmdHistory[nCmdCursor][0];
    memcpy(szCmdNow,pCmdHistory,MAX_CMD_LEN);
    nCmdInputCount = strlen(szCmdNow);
    nCmdInputCursor= nCmdInputCount;
    write(STDOUT_FILENO,szCmdNow,nCmdInputCount);
}

/******************************************************************************
* shell_deal_down_key - handle key 'down'
* input:
*    none
* return
*    none
*/

void shell_deal_down_key()
{
    if(nCmdCursor >= (nCmdIndex-1)) return;
    nCmdCursor ++;

    //clear all inputs
    shell_deal_double_esc();

    char* pCmdHistory = &szCmdHistory[nCmdCursor][0];
    memcpy(szCmdNow,pCmdHistory,MAX_CMD_LEN);
    nCmdInputCount = strlen(szCmdNow);
    nCmdInputCursor= nCmdInputCount;
    write(STDOUT_FILENO,szCmdNow,nCmdInputCount);
}

/******************************************************************************
* shell_deal_left_key - handle key 'left'
* input:
*    none
* return
*    none
*/

void shell_deal_left_key()
{
    if(nCmdInputCursor > 0)
    {
        char c = '\b';
        write(STDOUT_FILENO,&c,1);
        nCmdInputCursor--;
    }
}

/******************************************************************************
* shell_deal_right_key - handle key 'right'
* input:
*    none
* return
*    none
*/

void shell_deal_right_key()
{
    if(nCmdInputCursor < nCmdInputCount)
    {
        char* pCmd = szCmdNow;
        char c = pCmd[nCmdInputCursor];
        write(STDOUT_FILENO,&c,1);
        nCmdInputCursor++;
    }
}

/******************************************************************************
* shell_deal_enter_key - handle key 'Enter'
* input:
*    none
* return
*    none
*/

void shell_deal_enter_key()
{
    szCmdNow[nCmdInputCount] = '\0';
    char szTemp[] = {"\r\n"};
    write(STDOUT_FILENO,szTemp,strlen(szTemp));
    nCmdInputCount = 0;
    nCmdInputCursor = 0;

    if(strlen(szCmdNow) == 0)
        return;

    if(nCmdIndex == MAX_CMD_HISTORY)
    {
        char szTempCmd[MAX_CMD_HISTORY][MAX_CMD_LEN];
        memcpy(szTempCmd,&szCmdHistory[1][0],MAX_CMD_LEN*(MAX_CMD_HISTORY-1));
        memcpy(szCmdHistory,szTempCmd,MAX_CMD_LEN*(MAX_CMD_HISTORY-1));
        nCmdIndex = MAX_CMD_HISTORY-1;
        nCmdCursor = nCmdIndex;
    }

    memcpy(szCmdHistory[nCmdIndex],szCmdNow,MAX_CMD_LEN);

    nCmdIndex++;
    nCmdCursor = nCmdIndex;
}


/******************************************************************************
* shell_deal_tab - handle key 'tab'
* input:
*    none
* return
*    none
*/
 
void shell_deal_tab()
{
    int matchNum;
    int matchIndex;
    int lenDiff;
    int  cmdBufLen = 0;
    char cmdPre[MAX_CMD_LEN] = {0};

    cmdBufLen = nCmdInputCursor;
    szCmdNow[cmdBufLen] = '\0';

    strcpy(cmdPre, szCmdNow);
    matchNum = get_full_cmd_match(cmdPre);

    memset(cmdShowBuf, 0, sizeof(cmdShowBuf));
    if (matchNum == 1)
    {
        strcpy(cmdShowBuf, cmdMatchBuf[0]);

        lenDiff = strlen(cmdShowBuf)-strlen(cmdPre);
        write(STDOUT_FILENO, &cmdShowBuf[cmdBufLen], lenDiff);

        strcpy(szCmdNow, cmdShowBuf);
        nCmdInputCursor += lenDiff;
        nCmdInputCount += lenDiff;
    }
    else
    {
        strcat(cmdShowBuf, "\r\n");

        for (matchIndex = 0; matchIndex < matchNum; matchIndex++)
        {
            strcat(cmdShowBuf, cmdMatchBuf[matchIndex]);
            strcat(cmdShowBuf, "    ");
            if ((matchIndex+1)%4 == 0)
            {
                strcat(cmdShowBuf, "\r\n");
            }
        }
        strcat(cmdShowBuf, "\r\n");
        strcat(cmdShowBuf, szPrompt);
        strcat(cmdShowBuf, szCmdNow);
        set_out_str(cmdShowBuf);
    }
    memset(cmdMatchBuf, 0, sizeof(cmdMatchBuf) );
    cmdMatched = 0;
}

/******************************************************************************
* shell_get_line - read whole command line string
* input:
*    none
* return
*    none
*/

int  shell_get_line()
{
    int bGetEnter = 0;
    while(1)
    {
        char input;
        int ret;

//      input = osp_getc();
#if 1
        ret = osp_getcnew();
        if(-1 == ret)
        {
            return -1;
        }
        else
        {
            input = ret;
        }
#endif
        switch(waitKeyState)
        {
            case WKS_WAIT :
                if(spu_isprint(input))
                    shell_deal_input(input);
                else
                {
                    if(input == '\t')
                    {
                        shell_deal_tab();
                    }
                    else if(input == KEY_BACKSPACE)
                    {
                        shell_deal_backspace();
                    }
                    else if(input == KEY_ENTER)
                    {
                        shell_deal_enter_key();
                        bGetEnter = 1;
                    }
                    else if(input == '\x1b')
                        waitKeyState = WKS_RECV1B;
                    else
                        waitKeyState = WKS_WAIT;
                }
                break;

            case WKS_RECV1B:
                if(input == '\x1b') 
                {
                    shell_deal_double_esc();
                    waitKeyState = WKS_RECV1B;
                }
                else if(input == '[')   //maybe "up/down/left/right"
                {
                    waitKeyState = WKS_UDLR;
                }
                else  //after pressing 'ESC'
                {
                    if(spu_isprint(input))
                        shell_deal_input(input);
                    waitKeyState = WKS_WAIT;
                }
                break;

            case WKS_UDLR:
                if(input == 'A')          //up
                    shell_deal_up_key();
                else if(input == 'B')     //down
                    shell_deal_down_key();
                else if(input == 'D')     //left
                    shell_deal_left_key();
                else if(input == 'C')     //right
                    shell_deal_right_key();
                else if(input == 51)      //maybe key 'delete'
                {
                    waitKeyState = WKS_DEL;
                    break;
                }
                else
                {
                    if(spu_isprint(input))
                        shell_deal_input(input);
                }
                waitKeyState = WKS_WAIT;
                break;

            case WKS_DEL:
                if(input == 126)
                    shell_deal_delete();
                else
                {
                    if(spu_isprint(input))
                        shell_deal_input(input);
                }
                waitKeyState = WKS_WAIT;
                break;

            default:
                break;
        }

        if(bGetEnter)
        {
            break;
        }
    }
    return 0;
}


void spu_csu_int_cnt(void)
{
    char pbuf[2048];    
    uint32_t len      = 0;
    uint32_t ulNum    = 0;
    uint32_t ulCnt    = 0;    
	int32_t apeId     = get_core_id();
    stCoreInt* apeCoreIntInfo = (stCoreInt*)APE_INT_INFO_ADDR + APE_INT_MAXNUM*apeId;

    len = sprintf(pbuf,"\n\r%-8s%-16s%-8s%-16s\n\r","CoreId", "Inttype", "Intnum",  "IntCnt");

    ulNum = do_read_volatile(&(apeCoreIntInfo[APE_INT_TX_SLOT].intNum));
    ulCnt = do_read_volatile(&(apeCoreIntInfo[APE_INT_TX_SLOT].intCnt));
    len +=sprintf(pbuf +len,"%-8u%-16s%-8u%u\n\r", apeId, "APE_INT_TX_SLOT", ulNum, ulCnt);

    ulNum = do_read_volatile(&(apeCoreIntInfo[APE_INT_RX_SLOT].intNum));
    ulCnt = do_read_volatile(&(apeCoreIntInfo[APE_INT_RX_SLOT].intCnt));
    len +=sprintf(pbuf +len,"%-8u%-16s%-8u%u\n\r", apeId, "APE_INT_RX_SLOT", ulNum, ulCnt);

    ulNum = do_read_volatile(&(apeCoreIntInfo[APE_INT_STC_0US].intNum));
    ulCnt = do_read_volatile(&(apeCoreIntInfo[APE_INT_STC_0US].intCnt));
    len +=sprintf(pbuf +len,"%-8u%-16s%-8u%u\n\r", apeId, "APE_INT_STC_0US", ulNum, ulCnt);

    ulNum = do_read_volatile(&(apeCoreIntInfo[APE_INT_STC].intNum));
    ulCnt = do_read_volatile(&(apeCoreIntInfo[APE_INT_STC].intCnt));
    len +=sprintf(pbuf +len,"%-8u%-16s%-8u%u\n\r", apeId, "APE_INT_STC", ulNum, ulCnt);

    spu_shellinfo_to_arm(pbuf, len, UCP4008_OSP_SHELL);

    return;
}

void spu_csu_stop_cfg(uint8_t ucstop, uint8_t ucadvance)
{    
    if(ucstop > 1)
    {
        UCP_PRINT_EMPTY("spu_csu_stop_cfg ucstop:%u ucadvance:%u\n", ucstop, ucadvance);
        return;
    }
    
	do_write(CSU_STOP_CMD_ADDR, ucstop);
	
	//do_write(CSU_ADVANCE_US_ADDR, ucadvance);
	do_write(CSU_TX_ADVANCE_SAMPLE, ucadvance);
    
    return;
}

#if 0
void spu_shellinfo_to_arm(char* pbuf, int ulLen, uint8_t u8PktType)
{    
    uint16_t u16offset       = SPU_SW_MSG_INFO_SIZE;
    int32_t  i32core_id      = get_core_id();
    uint8_t  ret             = 0;    
    uint8_t  u8flag          = 0;
    int8_t   *pi8buf         = NULL;
    uint8_t  u8shell_index   = i32core_id + 24;
    spu_sw_msg_info_t stMsgHead;
    spu_sw_msg_info_t * pstsw_msg_info = NULL;
    
    if (NULL == pbuf)
    {
        UCP_PRINT_ERROR("spu_shellinfo_to_arm pbuf is null\n");
        return;
    }
        
    do{
        
        pi8buf = spu_sw_mem_malloc(u8shell_index);
        if (NULL == pi8buf)
        {
            UCP_PRINT_ERROR("spu_shellinfo_to_arm call spu_sw_mem_malloc return null\n");
            return ;
        }

        memcpy_ucp(pi8buf, pbuf, ulLen);

        stMsgHead.u8PktType    = u8PktType;
        stMsgHead.u16DataLen   = ulLen+SPU_SW_MSG_INFO_SIZE;
        stMsgHead.u8CoreId     = (uint8_t)i32core_id;
        
        if(stMsgHead.u16DataLen > SHELL_MAX_LEN_OF_PKG)
        {
            pi8buf = pi8buf + u8flag*SHELL_MAX_LEN_OF_PKG;
            stMsgHead.u16DataLen -= SHELL_MAX_LEN_OF_PKG;
            u8flag++;
        }
        else
        {
            pi8buf = pi8buf + u8flag*SHELL_MAX_LEN_OF_PKG;
            u8flag = 0;
        }
        
        UCP_PRINT_ERROR("spu_shellinfo_to_arm u8flag:%u\n", u8flag);
        UCP_PRINT_ERROR("spu_shellinfo_to_arm u8PktType:%u u16DataLen:%u\n", stMsgHead.u8PktType, stMsgHead.u16DataLen);

        pstsw_msg_info = (spu_sw_msg_info_t *)(pi8buf - u16offset);
        memcpy_ucp((void *)pstsw_msg_info, (void *)&stMsgHead, u16offset);

        ret = spu_sw_enque(u8shell_index++, pi8buf);
        if (0 != ret)
        {        
            UCP_PRINT_ERROR("spu_shellinfo_to_arm ret:%u\n", ret);
            return ;
        }
        
    }while(0 < u8flag);
    
    return;
}

#endif

void spu_shellinfo_to_arm(char* pbuf, int ulLen, uint8_t u8PktType)
{    
    spu_sw_msg_info_t stMsgHead;
    uint16_t u16offset       = SPU_SW_MSG_INFO_SIZE;
    int32_t  i32core_id      = get_core_id();
    uint8_t  ret             = 0;
    int8_t   *pi8buf         = NULL;
    uint8_t  u8shell_index   = i32core_id + 24;
    
    if (NULL == pbuf)
    {
        UCP_PRINT_EMPTY("ERROR:osp msg start ret:%u\n", ret);
        return;
    }

    pi8buf = spu_sw_mem_malloc(u8shell_index);
    if (NULL == pi8buf)
    {
        UCP_PRINT_EMPTY("osp_shellinfo_to_arm call spu_sw_mem_malloc return null\n");
        return ;
    }            
    
    memcpy_ucp(pi8buf, pbuf, ulLen);


    stMsgHead.u8PktType    = u8PktType;
    stMsgHead.u16DataLen   = ulLen+SPU_SW_MSG_INFO_SIZE;
    stMsgHead.u8CoreId     = (uint8_t)i32core_id;

    spu_sw_msg_info_t * pstsw_msg_info = (spu_sw_msg_info_t *)(pi8buf - u16offset);
    memcpy_ucp((void *)pstsw_msg_info, (void *)&stMsgHead, u16offset);

    ret = spu_sw_enque(u8shell_index, pi8buf);
    if (0 == ret)
    {        
        UCP_PRINT_EMPTY("osp_shellinfo_to_arm ret:%u\n", ret);
        return ;
    }

    return;
}


void spu_shell_proc(spu_sw_msg_info_t *pMsg)
{    
    int32_t ret;

    if (NULL == pMsg)
    {
        return;
    }
    
    /*arm 发过来的shell消息*/
    if(UCP4008_OSP_SHELL == pMsg->u8PktType)
    {    
        ret = get_cmd_arg((char *)pMsg->i8Data); 
        if(-1 == ret)
            return ;
        ret = exec_cmd();
        //set_prompt();
    }    
   
    return;

}

void spu_shell_task(void)
{
    uint8_t u8loop              = g_core_id + 12;
    spu_sw_msg_info_t *psw_msg  = NULL;

    debug_write(DBG_DDR_COMMON_IDX(g_core_id, 20), ++gu32_osp_shell_task_cnt);
    
    /* 从软队列里取出 */
    if(0 == spu_sw_deque(u8loop, (uint32_t **)&psw_msg))
    {
        debug_write(DBG_DDR_COMMON_IDX(g_core_id, 21), psw_msg);
        debug_write(DBG_DDR_COMMON_IDX(g_core_id, 22), &psw_msg);
        debug_write(DBG_DDR_COMMON_IDX(g_core_id, 23), ++gu32_osp_shell_task_rev);
        spu_shell_proc(psw_msg);
    }

    return;
}




