⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 initm803xx.c

📁 m80320 VoIP DSP驱动源码
💻 C
📖 第 1 页 / 共 3 页
字号:
        Modem_Addr=(unsigned long *)(CSM_addr+TX_FIFO_SIZE);
        while( Swap_Word(*(Modem_Addr)) >= 0x80)
        {
            ;
        }
        
        for(j = 0; j < 30; j++)
        {
            ;
        }
        Modem_Addr=(unsigned long *)(CSM_addr + HOST_START_DATA_ADD);
        #if 0  /* 由于pw指针已经是网络字节序,因此不再需要转换 */
        *Modem_Addr = Swap_Word(*pw);
        #else
        *Modem_Addr = *pw;
        #endif
        pw ++;
    }
}

/*write 60000 byte to M803xx 64M SDRAM in a write circle*/
LOCAL void LoadData_ToCSM(unsigned long *pw,unsigned long size,unsigned long base_addr,unsigned long CSM_addr)
{
    MBOX_PACKET msg;
    unsigned short bCount;

    while (size)
    {
        bCount = (0xea60 < size) ? 0xea60 : size; /* 60000 Byte */

        while ((ReadFromRegister(FIFO_STA_REG,CSM_addr) & TXE_MASK) == 0)
        {
            ;
        }
        if ( bCount <=0xff )
        {
            trans_data_tofifo(pw,bCount,CSM_addr);
            WriteToMbox((unsigned short)bCount,(unsigned short)(base_addr>>16),
                        (unsigned short)base_addr,PCI_BRM_FIFOWRITE,CSM_addr);
        }
        else
        {
            WriteToMbox((unsigned short)bCount,(unsigned short)(base_addr>>16),
                        (unsigned short)base_addr,PCI_BRM_FIFOWRITE,CSM_addr);
            trans_data_tofifo(pw,bCount,CSM_addr);
        }
        WriteToRegister(FIFO_STA_REG,CSM_addr,TXM3IAK_MASK);
        ReadFromMbox(&msg,CSM_addr);
        if (msg.message != PCI_BRM_CMD_ACK)  /*BspOnRedLed()*/
        {
            ;/*这里是否有相应的提示信息*/
        }
        size = size - bCount;
        base_addr = base_addr + bCount;
        pw = (unsigned long *)(pw + bCount/4);
    }
}

BOOL Programstart(unsigned long prog_entry,unsigned long CSM_addr)
{
    MBOX_PACKET msg;

    if(!WriteToMbox(0,(unsigned short)(prog_entry>>16),(unsigned short)prog_entry,PCI_BRM_PROGSTART,CSM_addr))
       return FALSE;
    if(!ReadFromMbox(&msg,CSM_addr)) return FALSE;

    if (msg.message != SUPVSR ) return FALSE;
    return TRUE;
}

LOCAL unsigned char DownLoadFirmware(unsigned long CSM_addr)
{
    unsigned long     Addrtemp, fat_offset,dest;
    unsigned long     fat_size, file_offset_next, *FirmWare_File_Header;
    volatile unsigned long     *pw,prog_entry;
    FAT_AIF_HEADER     fat_aif_header,*fataif;
    /* download CODE*/
    pw=(unsigned long *)(bDmFile + 0x80); /*code_offset*/
    LoadData_ToCSM((unsigned long *)pw,aif_header.image_readonly_size,aif_header.image_base,CSM_addr);
/*  if(!CheckLoadedData(pw,aif_header.image_readonly_size,aif_header.image_base,CSM_addr))
        return FALSE;*/

    /* download data*/
    pw=(unsigned long *)(bDmFile + 0x80 + aif_header.image_readonly_size);
    dest = aif_header.image_base + aif_header.image_readonly_size;
    LoadData_ToCSM((unsigned long *)pw,aif_header.image_readwrite_size,dest,CSM_addr);
/*  if(!CheckLoadedData(pw,aif_header.image_readwrite_size,dest,CSM_addr))
        return FALSE;*/

    /*download fat*/
    fat_offset = aif_header.first_fat;
    while(fat_offset)
    {

        FirmWare_File_Header = (unsigned long *)(bDmFile + fat_offset);

        fataif = (FAT_AIF_HEADER*) FirmWare_File_Header;

        fat_aif_header = *fataif;                       /* set the fat header struct */

        file_offset_next = Swap_Word(*(FirmWare_File_Header));     /* 1st byte is offset */

        Addrtemp = Swap_Word(*(FirmWare_File_Header+0x01));        /* 2ed byte is addr */

        fat_size = Swap_Word(*(FirmWare_File_Header+0x02));        /* 3th byte is size */

        pw = (unsigned long *)(bDmFile + fat_offset + 0x002c);
        if( (fat_aif_header.region_name[0]!=0x56) ||
            (fat_aif_header.region_name[1]!=0x45) ||
            (fat_aif_header.region_name[2]!=0x43) ||
            (fat_aif_header.region_name[3]!=0x54) ||
            (fat_aif_header.region_name[4]!=0x4f) ||
            (fat_aif_header.region_name[5]!=0x52) ||
            (fat_aif_header.region_name[6]!=0x53) ||
            (fat_aif_header.region_name[7]!=0x5f) ||
            (fat_aif_header.region_name[8]!=0x4c) ||
            (fat_aif_header.region_name[9]!=0x52) )
        {
            if(fat_size)
            {
                LoadData_ToCSM((unsigned long *)pw,fat_size,Addrtemp,CSM_addr);
            }
        }
        fat_offset=file_offset_next;
    }
    prog_entry = aif_header.image_base + aif_header.bl_image_entry_point;
    if(!Programstart(prog_entry,CSM_addr)) return FALSE;

    return TRUE;
}

BOOL M803xx_ZeroInit(UINT32 Addr)
{
    UINT32 bcount,size,memaddr,database;

    bcount = 0x10000;
    size = aif_header.image_zero_init_size;
    if(aif_header.data_base)
       database = aif_header.data_base;
    else
       database = aif_header.image_base + aif_header.image_readonly_size;

    memaddr = database + aif_header.image_readwrite_size;

    while(size)
    {
        if(size < bcount)
        {
            bcount = size;
        }
        
        if(!WriteToMbox( (UINT16)memaddr, (UINT16)(memaddr>>16), bcount, PCI_BRM_ZEROFILL, Addr))
        {
            return FALSE;
        }
        else
        {
            ;
        }
        size -= bcount;
        memaddr += bcount;
    }
    return TRUE;
}

LOCAL BOOL TDM_Setup(unsigned long CSM_addr)
{
    MBOX_PACKET msg;

#if 0
    WriteToMbox(0x0,0x0400,0x8320,0xd7ff,CSM_addr);
#else
    WriteToMbox(0x0,0x0400,0x9b20,0xd7ff,CSM_addr);
#endif
    ReadFromMbox(&msg,CSM_addr);
    if (msg.message == PCI_BRM_ERRIND) return FALSE;
    return TRUE;
}

/*************************************************************************/
/* Function name: InitChan                                               */
/* Description  : Initialize Channel                                     */
/* Return type  : void                                                   */
/* Argument     : void                                                   */
/* Author/Date  : Cao WanMing/2003-1-16 15:57                            */
/* Note:                                                                 */
/*                                                                       */
/*************************************************************************/
LOCAL void InitChan(UINT8 PinNo, UINT32 Addr)
{
    int ackMsgNum;
    UINT8 PortNum;
    MBOX_PACKET msg;
    unsigned short chan,i,creatAck;
    UINT32 rxBufAddrH,rxBufAddrL;
    UINT32 *bufAddr, *buf;
    void *tempAddr;
    STATUS rc = ERROR;

    for(chan = 0; chan < PORTS_OF_CHIP; chan++)
    {
        rc = ERROR;
        PortNum = chan + PORTS_OF_CHIP * PinNo;

        /* 配置通道类型和时隙 */
        if (TRUE != WriteToMbox(0x0, (UINT16)chan, 0x2, 0xd0ff, Addr))
        {    
            printf("When Init slot(%d) chan(%d), WriteToMbox  failed!!!\n", PinNo, chan);
            ASSERT(0);
        }

        #if M803xx_INIT_DEBUG
        M80320_PRINTF("chan = %d, j = %d\n", chan, j);
        #endif
        creatAck = 0;
        ackMsgNum = 0;
        
        for(i = 0; i < 50; i++)
        {
            if(!ReadFromMbox(&msg,Addr)) 
                continue ;
            if((msg.message == SUPVSR_CREATE_CHANNEL_ACK) && (msg.p0 == LFXS_UP))
            {
                creatAck = 1;
                m_channel[PortNum].ChanId = msg.p1;
                m_channel[PortNum].TimeSlot = msg.p2;
                ackMsgNum ++;
            }
            
            if((msg.message & 0xFF00) == CMD_DATAREQ)
            {
                /*2006-8-5 ZhengQishan 1 - 可以发送数据,0 - 不能发送数据*/
                m_channel[PortNum].tx_data_requested = 1 /*msg.p0*/;
                ackMsgNum ++;
            }
            
            if((msg.message & 0xFF00) == CMD_CMDREQ)
            {
                m_channel[PortNum].tx_cmd_requested = 1;
                ackMsgNum ++;
            }

            /*如果三个消息都已经接收到,中断循环*/
            if(3 == ackMsgNum)
                break;
        }
        
        if(creatAck == 1)
        {
            m_channel[PortNum].Active = IDLE;
            #if M803xx_INIT_DEBUG
            M80320_PRINTF("M803xx Create_channel Command Ok");
            #endif
        }
        else
        {
            printf("InitChan: Create channel {slot(%d) chan(%d)} failed!!!\n", PinNo, chan);
            ASSERT(0);
        }
    }
    Init_Port_Channel(PinNo);

    /* 向这些通道发送初始化命令 */
    for(chan = 0; chan < PORTS_OF_CHIP; chan++)
    {
        PortNum = chan + PORTS_OF_CHIP * PinNo;
        if(m_channel[PortNum].Active == FAIL) continue;

        if((m_channel[PortNum].Port) < ((PinNo+1)*M803XX_MAX_PORT_NUM))
        {
            WriteToMbox(0,0x0001,(UINT16)(m_port[m_channel[PortNum].Port].Slot),CMD_SETTSA|chan,Addr);
            M80320_PRINTF("Port %d Slot %d\n", m_channel[PortNum].Port, m_port[m_channel[PortNum].Port].Slot);
        }

        M803xx_ALLOC_PCI_ADDR(bufAddr,tempAddr,buf);
        if (buf == NULL)
        {
            M80320_PRINTF("M803xx Init PktAlloc Fail\n");
        }
        else
        {
            M80320_PRINTF("Port %d PktAlloc Pci Addr = %x, Mem Addr = %x\n",
                          PortNum, (unsigned int)bufAddr, (unsigned int)buf);

            PciReadBuf[PortNum] = bufAddr;
            rxBufAddrH = ((UINT32)((UINT8 *)bufAddr+PACKET_START_SIZE)) >> 16;
            rxBufAddrL = ((UINT32)((UINT8 *)bufAddr+PACKET_START_SIZE)) & 0x0000ffff;
            WriteToMbox(0, 0, 0, CMD_SETSYNC | chan, Addr);
            WriteToMbox(rxBufAddrL,rxBufAddrH,0x400,CMD_PCIREQ | chan, Addr);
        }
        WriteToMbox(0, 0, 0x80, CMD_CMDREQ|chan, Addr);
    }

    M80320_PRINTF("PowerOnStart Ok\n");
}

void M803xx_Init(UINT8 PinNo, UINT32 Addr)
{
    int i;
    STATUS rc = ERROR;
    
    aif_open(&aif_header);

    /* 重复三次,都失败则上报初始化失败 */
    for(i = 0; i < 3; i++)
    {
        if(!M803xx_HandShake(Addr))
        {
            printf("Slot(%d) M803xx Hand Shake Fail\n", (int)PinNo);
            continue;
        }
        M80320_PRINTF("M803xx Hand Shake OK\n");

        M803xx_DMAFIFO_Enable(Addr);

        if(!M803xx_DeviceInit(Addr))
        {
            printf("Slot(%d) M803xx DeviceInit Fail\n", (int)PinNo);
            continue;
        }
        M80320_PRINTF("M803xx DeviceInit OK\n");

        if(!DownLoadFirmware(Addr))
        {
            printf("Slot(%d) M803xx Download Firmware Fail\n", (int)PinNo);
            continue;
        }
        M80320_PRINTF("M803xx Download Firmware OK\n");

        if(!M803xx_ZeroInit(Addr))
        {
            printf("Slot(%d) M803xx ZeroInit Fail\n", (int)PinNo);
            continue;
        }
        M80320_PRINTF("M803xx ZeroInit OK\n");

        if(!TDM_Setup(Addr))
        {
            printf("Slot(%d) M803xx Setup TDM Fail\n", (int)PinNo);
            continue;
        }
        M80320_PRINTF("M803xx Setup TDM OK\n");

        /* 置标志:芯片下载成功,可以工作 */
        PinStatus[PinNo] = TRUE;

        /* 下载完毕,初始化芯片上所有的通道 */
        InitChan(PinNo, Addr);

        M80320_PRINTF("M803xx Init OK\n");
        rc = OK;
        break;
    }
    if (OK != rc)
    {
        printf("Init M803xx which in Slot(%d) is failed!!!", (int)PinNo);
        ASSERT(0);
    }
}

/*-----------------------------
* setPortDefaultArg - 设置语音通道的缺省状态值
*
* Description:
* 
* Argument:
*   int PortNo      - PortNo = (slot - 1) * 8 (每一个槽位最多8个端口) + port - 1
*
* Modified history
*------------------------------
* 2006-6-15 15:13 ZhengaQishan Created.
*
**/
void initGlobalVariableForM80320(void)
{
    static int firstTimeInitM80320GV = 0;

    if (0 == firstTimeInitM80320GV)
    {
        memset(m_txmbox, 0, MAX_PIN_NUM * sizeof(M80320_QUEUE));
        memset(m_OpenChannelMailboxQueue, 0, MAX_PIN_NUM*M803XX_MAX_PORT_NUM*sizeof(M80320_QUEUE));
        memset(m_TxDataQueue, 0, MAX_PIN_NUM*M803XX_MAX_PORT_NUM*sizeof(M80320_QUEUE));

        memset(m_port, 0, MAX_PIN_NUM*M803XX_MAX_PORT_NUM*sizeof(M803xx_PORT_STATE));
        memset(m_channel, 0, MAX_PIN_NUM*PORTS_OF_CHIP*sizeof(CHANNEL));
        memset(Receive_Message, 0, MAX_PIN_NUM*MAX_RX_MSG_NUM*sizeof(MBOX_PACKET));

        firstTimeInitM80320GV = 1;
    }
    else
        printf("All global variable have been initilized.\n");
}

/*************************************************************************
* Function name: InitTxMboxQueue                                       
* Description  : Initialize TX Mailbox Queue                            
* Return type  : void 
*

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -