core_spi.c

来自「6440linuxDriver的源代码」· C语言 代码 · 共 647 行

C
647
字号
#include "core_header.h"//#include "com_type.h"#include "spi_hal.h"#include "core_spi.h"#if defined(SUPPORT_CSMI)static MV_U8           SPICmd[16];MV_U8   ATMEL_SPI_CMD[16] = {    0x06, 0x04, 0x05, 0x01, 0x03, 0x02, 0x52, 0x62, 0x15};MV_U8   MXIC_SPI_CMD[16] = {    0x06, 0x04, 0x05, 0x01, 0x03, 0x02, 0x20, 0x60, 0x9F};#if defined( SPIRegR32 )#undef SPIRegR32#endif#if defined( SPIRegW32 )#undef SPIRegW32#endif#define SPIRegR32       MV_IOR32#define SPIRegW32       MV_IOW32/**********************************************************************************/MV_U32SPI_Cmd(    MV_U8   cmd){    if( cmd >= sizeof( SPICmd ) )        return -1;    return SPICmd[cmd];}/**********************************************************************************/intOdinSPI_WaitDataReady(    AdapterInfo *pAI,    MV_U32         timeout){    MV_PVOID  BarAdr = pAI->bar[2];    MV_U32  i, dwTmp;//    MV_U32  timer;    for( i=0; i<timeout; i++ )//    timer = Timer_GetTime();//    while( !Timer_CheckTime( timer, 3 ) )    {        dwTmp = SPIRegR32( BarAdr, ODIN_SPI_CTRL_REG );//        if( dwTmp & SPI_CTRL_SpiRdy )        //spi rdy bit will lost some times.        //check spi start bit clear        if( !( dwTmp & SPI_CTRL_SpiStart ) )        {//            SPI_DBG( ( "WaitDataReady %ld\n", i ) );            return 0;        }        DelayUSec( 10 );    }    SPI_DBG( ( "%d timeout\n", __LINE__ ) );    return -1;}intOdinSPI_WaitCmdIssued(    AdapterInfo *pAI){    MV_PVOID  BarAdr = pAI->bar[2];    MV_U32  i, dwTmp;//    MV_U32  timer;    for( i=0; i<3000; i++ )//    timer = Timer_GetTime();//    while( !Timer_CheckTime( timer, 0.5 ) )    {        dwTmp = SPIRegR32( BarAdr, ODIN_SPI_CTRL_REG );        if( !( dwTmp & SPI_CTRL_SpiStart ) )        {            return 0;        }        DelayUSec( 20 );    }    return -1;}intOdinSPI_BuildCmd(    MV_U32      *dwCmd,    MV_U8       cmd,    MV_U8       read,    MV_U8       length,    MV_U32      addr){    MV_U32  dwTmp;    dwTmp = ( ( MV_U32 )cmd << 24 )|( (MV_U32)length << 19 );    if( read )    {        dwTmp|= MV_BIT( 23 );    }    if (addr != MV_MAX_U32)    {	    dwTmp|= MV_BIT( 22 );	    dwTmp|= ( addr & 0x0003FFFF );    }    *dwCmd = dwTmp;    return 0;}intOdinSPI_IssueCmd(    AdapterInfo *pAI,    MV_U32      cmd){    MV_PVOID  BarAdr = pAI->bar[2];    int     retry;    for( retry=0; retry<1; retry++ )    {        SPIRegW32( BarAdr, ODIN_SPI_CTRL_REG, SPI_CTRL_VenderEnable );        SPIRegW32( BarAdr, ODIN_SPI_CMD_REG, cmd );        SPIRegW32( BarAdr, ODIN_SPI_CTRL_REG, SPI_CTRL_VenderEnable | SPI_CTRL_SpiStart );    }                return 0;}intOdinSPI_RDSR(    AdapterInfo *pAI,    MV_U8       *sr){    MV_PVOID  BarAdr = pAI->bar[2];    MV_U32  dwTmp;//    int     retry;    OdinSPI_BuildCmd( &dwTmp,                   (MV_U8)SPI_Cmd( SPI_INS_RDSR ),                   1,                   1,                   -1 );    OdinSPI_IssueCmd( pAI, dwTmp );    if( 0 == OdinSPI_WaitDataReady( pAI, 10000 ) )    {        dwTmp = SPIRegR32( BarAdr, ODIN_SPI_DATA_REG );        *sr = (MV_U8)dwTmp;        return 0;    }    else    {        SPI_DBG( ( "%d timeout\n", __LINE__ ) );    }    return -1;}intOdinSPI_PollSR(    AdapterInfo *pAI,    MV_U8       mask,    MV_U8       bit,    MV_U32      timeout){    MV_U32  i;    MV_U8   sr;//    MV_U32  timer;    for( i=0; i<timeout; i++ )//    timer = Timer_GetTime();//    while( !Timer_CheckTime( timer, 3 ) )    {        if( 0 == OdinSPI_RDSR( pAI, &sr ) )        {//            SPI_DBG( ( "sr:%2.2X\n", sr ) );            if( ( sr & mask )==bit )                return 0;        }        else            SPI_DBG( ( "%d\n", __LINE__ ) );        DelayUSec( 10 );    }    SPI_DBG( ( "%d\n", __LINE__ ) );    return -1;}intOdinSPI_WREN(    AdapterInfo *pAI){    MV_U32  dwTmp;    OdinSPI_BuildCmd( &dwTmp,                   (MV_U8)SPI_Cmd( SPI_INS_WREN ),                   0,                   0,                   -1 );    OdinSPI_IssueCmd( pAI, dwTmp );    if( 0!=OdinSPI_WaitDataReady( pAI, 10000 ) )    {        return -1;    }    if( 0 == OdinSPI_PollSR( pAI, 0x03, 0x02, 300000 ) )    {        return 0;    }    SPI_DBG( ( "%d\n", __LINE__ ) );    return -1;}intOdinSPI_WRDI(    AdapterInfo *pAI){    MV_U32 dwTmp;    OdinSPI_BuildCmd( &dwTmp,                   (MV_U8)SPI_Cmd( SPI_INS_WRDI ),                   0,                   0,                   -1 );    OdinSPI_IssueCmd( pAI, dwTmp );    OdinSPI_WaitDataReady( pAI, 10000 );    if( 0 == OdinSPI_PollSR( pAI, 0x03, 0, 300000 ) )    {        return 0;    }    SPI_DBG( ( "%d\n", __LINE__ ) );    return -1;}intOdinSPI_SectErase(    AdapterInfo *pAI,    MV_U32      addr){    MV_U32  dwTmp;    if( -1 == OdinSPI_WREN( pAI ) )        return -1;    OdinSPI_BuildCmd( &dwTmp,                   (MV_U8)SPI_Cmd( SPI_INS_SERASE ),                   0,                   0,                   addr );    OdinSPI_IssueCmd( pAI, dwTmp );    if( 0!=OdinSPI_WaitDataReady( pAI, 10000 ) )    {        return -1;    }    if( 0 == OdinSPI_PollSR( pAI, 0x03, 0, 300000 ) )    {        return 0;    }    SPI_DBG( ( "%d\n", __LINE__ ) );    return -1;}intOdinSPI_ChipErase(    AdapterInfo *pAI){    MV_U32 dwTmp;    if( -1 == OdinSPI_WREN( pAI ) )        return -1;    OdinSPI_BuildCmd( &dwTmp,                   (MV_U8)SPI_Cmd( SPI_INS_CERASE ),                   0,                   0,                   -1 );    OdinSPI_IssueCmd( pAI, dwTmp );    if( 0!=OdinSPI_WaitDataReady( pAI, 10000 ) )    {        return -1;    }    if( 0 == OdinSPI_PollSR( pAI, 0x03, 0, 300000 ) )    {        return 0;    }    SPI_DBG( ( "%d\n", __LINE__ ) );    return -1;}intOdinSPI_Write(    AdapterInfo *pAI,    MV_U32      Addr,    MV_U32      Data){    MV_PVOID  BarAdr = pAI->bar[2];    MV_U32 dwTmp;    OdinSPI_WREN( pAI );    SPIRegW32( BarAdr, ODIN_SPI_DATA_REG, Data );    OdinSPI_BuildCmd( &dwTmp,                   (MV_U8)SPI_Cmd( SPI_INS_PROG ),                   0,                   4,                   Addr );    OdinSPI_IssueCmd( pAI, dwTmp );    if( 0 != OdinSPI_WaitDataReady( pAI, 10000  ) )    {        SPI_DBG( ( "%d timeout\n", __LINE__ ) );        return -1;    }    if( 0 == OdinSPI_PollSR( pAI, 0x01, 0, 5000 ) )    {        return 0;    }    SPI_DBG( ( "%d timeout\n", __LINE__ ) );    return -1;}intOdinSPI_WriteBuf(    AdapterInfo *pAI,    MV_U32      Addr,    MV_U8       *Data,    MV_U32      Count){    MV_U32  i;    for( i=0; i<Count; i+=4 )    {        if( -1 == OdinSPI_Write( pAI, Addr + i, *(MV_U32*)&Data[i] ) )        {            SPI_DBG( ( "Write failed at %5.5x\n", Addr+i ) );            return -1;        }    }    return 0;}intOdinSPI_Read(    AdapterInfo *pAI,    MV_U32      Addr,    MV_U8       *Data,    MV_U8       Size){    MV_PVOID  BarAdr = pAI->bar[2];    MV_U32  i, dwTmp;    if( Size > 4 )        Size = 4;    OdinSPI_BuildCmd( &dwTmp,                   (MV_U8)SPI_Cmd( SPI_INS_READ ),                   1,                   Size,                   Addr );    OdinSPI_IssueCmd( pAI, dwTmp );    if( 0 == OdinSPI_WaitDataReady( pAI, 10000 ) )    {        dwTmp = SPIRegR32( BarAdr, ODIN_SPI_DATA_REG );        for( i=0; i<Size; i++ )        {            Data[i] = ((MV_U8*)&dwTmp)[i];        }        return 0;    }    else    {        SPI_DBG( ( "%d timeout\n", __LINE__ ) );    }    return -1;}intOdinSPI_ReadBuf(    AdapterInfo *pAI,    MV_U32      Addr,    MV_U8       *Data,    MV_U32      Count){    MV_U32      i, j;    MV_U32      tmpAddr, tmpData, AddrEnd;    MV_U8       *u8 = (MV_U8*)Data;    AddrEnd = Addr + Count;    tmpAddr = ALIGN( Addr, 4 );    j = ( Addr & ( MV_BIT( 2 ) - 1 ) );    if( j > 0 )    {        OdinSPI_Read( pAI, tmpAddr, (MV_U8*)&tmpData, 4 );        for( i=j; i<4; i++ )        {            *u8++ = ((MV_U8*)&tmpData)[i];        }        tmpAddr+= 4;    }    j = ALIGN( AddrEnd, 4 );        for(; tmpAddr < j; tmpAddr+=4 )    {        OdinSPI_Read( pAI, tmpAddr, (MV_U8*)&tmpData, 4 );        *((MV_U32*)u8) = tmpData;        u8+= 4;    }    if( tmpAddr < AddrEnd )    {        OdinSPI_Read( pAI, tmpAddr, (MV_U8*)&tmpData, 4 );        Count = AddrEnd - tmpAddr;        for( i=0; i<Count; i++ )        {            *u8++ = ( (MV_U8*)&tmpData )[i];        }    }        return 0;}intOdinSPI_RMWBuf(    AdapterInfo *pAI,    MV_U32      Addr,    MV_U8       *Data,    MV_U32      Count,    MV_U8       *Buf){MV_U32  tmpAddr;MV_U32  SecSize;MV_U32  i, StartOfSec;    SecSize = pAI->FlashSectSize;    tmpAddr = ALIGN( Addr, SecSize );    while( Count > 0 )    {        StartOfSec = ( Addr - tmpAddr );        if( StartOfSec>0 || Count<SecSize )            OdinSPI_ReadBuf( pAI, tmpAddr, Buf, SecSize );        if( 0!=OdinSPI_SectErase( pAI, tmpAddr ) )            return -1;        for( i=StartOfSec; Count>0 && i<SecSize; i++ )        {            Buf[i] = *Data++;            Count--;        }        if( 0!=OdinSPI_WriteBuf( pAI, tmpAddr, Buf, SecSize ) )            return -1;        Addr+= (SecSize - StartOfSec);        tmpAddr+= SecSize;    }        return 0;}intOdinSPI_AtmelIdentify(    AdapterInfo *pAI){    MV_PVOID  BarAdr = pAI->bar[2];    MV_U32  dwTmp;        //atmel identify    OdinSPI_BuildCmd( &dwTmp,                   0x15,                   1,                   2,                   -1 );    OdinSPI_IssueCmd( pAI, dwTmp );    if( 0 == OdinSPI_WaitDataReady( pAI, 10000 ) )    {        dwTmp = SPIRegR32( BarAdr, ODIN_SPI_DATA_REG );        switch( dwTmp )        {            case 0x631f:                pAI->FlashID = AT25F2048;                pAI->FlashSize = 256L * 1024;                pAI->FlashSectSize = 64L * 1024;                return 0;        }                }    return -1;}intOdinSPI_MxicIdentify(    AdapterInfo *pAI){    MV_PVOID  BarAdr = pAI->bar[5];    MV_U32  dwTmp;    //mxic identify    OdinSPI_BuildCmd( &dwTmp,                   MXIC_SPI_CMD[SPI_INS_RDID],                   1,                   3,                   -1 );    OdinSPI_IssueCmd( pAI, dwTmp );    if( 0 == OdinSPI_WaitDataReady( pAI, 10000 ) )    {        dwTmp = SPIRegR32( BarAdr, ODIN_SPI_DATA_REG );        switch( dwTmp )        {            case 0x1220C2:                pAI->FlashID = MX25L2005;                pAI->FlashSize = 256L * 1024;                pAI->FlashSectSize = 4L * 1024;                return 0;        }    }    return -1;}intOdinSPI_Init(    AdapterInfo *pAI){//    MV_U32  dwTmp;    MV_U32  i;    MV_U8   *pSPIVendor;    pSPIVendor = NULL;        if( 0 == OdinSPI_AtmelIdentify( pAI ) )    {        pSPIVendor = ATMEL_SPI_CMD;    }    else if( 0 == OdinSPI_MxicIdentify( pAI ) )    {        pSPIVendor = MXIC_SPI_CMD;    }    if( pSPIVendor )    {        for( i=0; i<sizeof( SPICmd ); i++ )        {            SPICmd[i] = pSPIVendor[i];        }            return 0;    }            return -1;}intInitHBAInfo(    HBA_Info_Main *pHBAInfo){    int i;    MV_U8 *pU8;    pU8 = (MV_U8*)pHBAInfo;    for( i=0; i<sizeof( HBA_Info_Main ); i++ )        pU8[i] = 0xFF;    memcpy( pHBAInfo->signature, "MRVL", 4 );    return 0;}intGetHBAInfoChksum(    HBA_Info_Main *pHBAInfo){    MV_U32  i;    MV_U8   *pU8, cs;    cs = 0;    pU8 = (MV_U8*)pHBAInfo;    for( i=0; i<sizeof( HBA_Info_Main ); i++ )    {        cs+= pU8[i];    }    return cs;}intLoadHBAInfo(    AdapterInfo *pAI,    HBA_Info_Main *pHBAInfo){    if( 0!=OdinSPI_ReadBuf( pAI,                             pAI->FlashSize-sizeof( HBA_Info_Main ),                             (MV_U8*)pHBAInfo,                             sizeof( HBA_Info_Main ) ) )    {        return -1;    }    if( 0!=GetHBAInfoChksum( pHBAInfo ) )    {        InitHBAInfo( pHBAInfo );        return -1;    }    return 0;}#include <core_eeprom.c>#endif

⌨️ 快捷键说明

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