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 + -
显示快捷键?