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

📄 eeinfo.c

📁 CIRRUS 公司EP93XX系列CPU的WINCE下的BSP
💻 C
字号:
//**********************************************************************
//                                                                      
// Filename: eeinfo.c
//                                                                      
// Description: Reads the data from the ATMEL AT25F1024 eeprom.
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Use of this source code is subject to the terms of the Cirrus end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to 
// use this source code. For a copy of the EULA, please see the 
// LICENSE.RTF on your install media.
//
// Copyright(c) Cirrus Logic Corporation 2003, All Rights Reserved                       
//                                                                      
//**********************************************************************
#include <windows.h>
#include <hwdefs.h>
#include <clocks.h>
#include <debugtimer.h>
#include "drv_glob.h"
#include "eeinfo.h"


//
// Global Board information
//
BOARD_INFO gBoardInformation;
BOOL       gBoardInformationValid;

unsigned char pTemp[0x2000];


//
// Function prototypes
//
static void InitializeSPI(void);
static BOOL TestSPI(void);
static BOOL ReadEEWord(ULONG ulAddress, ULONG ulLength, PUCHAR pucData);
static BOOL ClearReceiveFifo(void);
static BOOL WaitTillTransmitFifoEmpty(void);

#define SPI_BYTETIME            10L
#define SPI_MINTIME             200L

//
// ATMEL SPI memory Instructions
//;
#define SPIEE_High_Address      0x08
#define SPIEE_SPACE             0x00     // White Space
#define SPIEE_WRSR              0x01     // Write Ststus Register
#define SPIEE_WRITE_LOW         0x02     //
#define SPIEE_WRITE_HIGH        0x0A     // = SPI_WRITE_LOW | SPI_High_Address
#define SPIEE_READ_LOW          0x03     //
#define SPIEE_READ_HIGH         0x0B     // = SPI_READ_LOW | SPI_High_Address
#define SPIEE_WRDI              0x04     // Reset the write enable latch
#define SPIEE_RDSR              0x05     // Read Ststus Register
#define SPIEE_WREN              0x06     // Set Write Enable Latch
#define SPIEE_RDID              0x15     // Read Manufaturor's ID
#define SPIEE_CHIPERASE         0x62     // Erase the chip   



//****************************************************************************
// GetBoardInformation
//****************************************************************************
// Reads the board information from an EEPROM.
// 
//
void GetBoardInformation(void )
{
    BOOL    bRet;
    PULONG   pul;
    PUCHAR  puc;
    ULONG   ulTemp;
    // int     x;

    //
    // Initialize the board information structure.
    //
    memset(&gBoardInformation, 0, sizeof(BOARD_INFO));
    
    //
    // Initialize the SPI device for reading the EEPROM.
    //
    InitializeSPI();

    //
    // Test the SPI device to make sure that it is an ATMEL
    //
    bRet =  TestSPI();
    if(bRet)
    {
        bRet =  ReadEEWord(0x1000, sizeof(BOARD_INFO), (PCHAR) &gBoardInformation);
        pul = (PULONG) &gBoardInformation;

        puc = (unsigned char *)pul;
        EdbgOutputDebugString( "EEINFO: EEInformation.\r\n");
        EdbgOutputDebugString( "EEINFO: 0x%x 0x%x 0x%x 0x%x.\r\n" , (ULONG) puc[0],  (ULONG) puc[1],  (ULONG) puc[2],  (ULONG) puc[3]);
        EdbgOutputDebugString( "EEINFO: 0x%x 0x%x 0x%x 0x%x.\r\n" , (ULONG) puc[4],  (ULONG) puc[5],  (ULONG) puc[6],  (ULONG) puc[7]);
        EdbgOutputDebugString( "EEINFO: 0x%x 0x%x 0x%x 0x%x.\r\n" , (ULONG) puc[8],  (ULONG) puc[9],  (ULONG) puc[10], (ULONG) puc[11]);
        EdbgOutputDebugString( "EEINFO: 0x%x 0x%x 0x%x 0x%x.\r\n" , (ULONG) puc[12], (ULONG) puc[13], (ULONG) puc[14], (ULONG) puc[15]);

        //
        // Mac Address.
        //
        EdbgOutputDebugString("MAC Address = 0x%x, 0x%x, 0x%x\r\n", 
                             (ULONG) gBoardInformation.MACAddress[0],
                             (ULONG) gBoardInformation.MACAddress[1],
                             (ULONG) gBoardInformation.MACAddress[2]);

        EdbgOutputDebugString("Board Name = %s\r\n", gBoardInformation.strEdbgName);

        if(bRet && !memcmp(&gBoardInformation.strSignature,"EMAC", 4))
        {
            gBoardInformationValid = TRUE;
        }
        else
        {
            gBoardInformationValid = FALSE;
        }
    }
    else
    {
        EdbgOutputDebugString("EEINFO: SPI Device Not detected.\r\n");
        gBoardInformationValid = FALSE;
    }


    //
    //Set GPIO pins 7 to disable the frame line.
    //
    ulTemp = *GPIO_PADR;
    *GPIO_PADR = ulTemp | 0x80;
}

//****************************************************************************
// InitializeSPI
//****************************************************************************
// Initializes the SPI device to access the eeprom  
// 
//
static void InitializeSPI(void)
{
    ULONG ulTemp;

    //
    // Set GPIO Pins 12 and 14 as outputs.
    //
    ulTemp = *GPIO_PBDDR;
    *GPIO_PBDDR = ulTemp | 0x50;

    //
    // Set GPIO pins 12 and 14 to high to disable the keyboard.
    //
    ulTemp = *GPIO_PBDR;
    *GPIO_PBDR = ulTemp | 0x50;

    //
    // Set GPIO pins 7 as an output.
    //
    ulTemp = *GPIO_PADDR;
    *GPIO_PADDR = ulTemp | 0x80;

    //
    // Clear GPIO pins 7 to enable the frame line.
    //
    ulTemp = *GPIO_PADR;
    *GPIO_PADR = ulTemp & ~0x80;


    //
    // Program the CR0 register.
    //        
    *SPI_CR0 =  SPICR0_FRF_MOTOROLA | SPICR0_SPO |
                SPICR0_SPH | (8-1) | (SPICR0_SCR_MASK & 0x600);

    //
    // Program the predivisor register.  This will give us an 
    // 14.7Mhz / ((6 +1) * 2) = Approx 1Mhz.
    //
    // The Max is 20Mhz for the AT25F1024. 
    //
    *SPI_CPSR = 2;

    //
    // Program the CR1 register.  
    //        
    *SPI_CR1 =  0;

    //
    // Hit the enable bit
    // 
    *SPI_CR1 = SPICR1_SSE;
}


//****************************************************************************
// TestSPI  
//****************************************************************************
// Tests to make sure that an SPI device is out there.
// 
// For Now always assume that you are able to communicate to the SPI device.
// 
// Return 0 - Fail
//        1 - SPI device found.
//
static BOOL TestSPI(void)
{
    ULONG ulManufacturer, ulDevice, ulTemp;
    // ULONGLONG   ullStart, ullMax, ullCurrent;

    //
    // Issue the command for reading the SPI Product ID register.
    //
    *SPI_DR = SPIEE_RDID;
    *SPI_DR =  0;
    *SPI_DR =  0;

    //
    // Wait until the transmit fifo is flushed.
    //
    WaitTillTransmitFifoEmpty();

    //
    // Read one byte and throw it away.
    //
    ulTemp = *SPI_DR;

    //
    // Read the Manufacturers code.
    //
    ulManufacturer = *SPI_DR;

    //
    // Read the device code.
    //
    ulDevice = *SPI_DR;

    //
    // Check to see if the Manufacturer is atmel if so return 1.
    //
    return (ulManufacturer ==0x1F);
}    


//****************************************************************************
//  ReadEEWord
//****************************************************************************
// Reads a 32bit word for an SPI EEprom
//
// Return 0 - Fail
//        1 - SPI device found.
//
BOOL ReadEEWord(ULONG ulAddress, ULONG ulLength, PUCHAR pucData)
{
    ULONG       ulCount, ulTransmitCount = 0;
    ULONG       ulReceiveCount = 0;
    volatile    ULONG       ulTemp;
    ULONGLONG   ullStart, ullMax, ullCurrent;
    BOOL        bRet;


    //
    // Make sure that the receive fifo is clear.
    //
    bRet = ClearReceiveFifo();
    if(!bRet)
    {
        EdbgOutputDebugString("EEINFO: ClearReceiveFifo Timeout.\r\n");
        return bRet;   
    }

    //
    // Send the Chip Read command.
    //        
    *SPI_DR = SPIEE_READ_LOW;

    //
    // Send the three byte address.
    //
    *SPI_DR = (ulAddress >> 16) & 0xFF;
    *SPI_DR = (ulAddress >> 8) & 0xFF;
    *SPI_DR = ulAddress  & 0xFF;

    //
    // Wait until we send 3 bytes.
    //
    ulCount = 0;
    ullStart = GetSystemTimeInUSec();
    ullMax   = ullStart + SPI_MINTIME + 3 * SPI_BYTETIME;

    do
    {
        //
        // Check to see if there are bytes to receive.
        //
        if(*SPI_SR & SPISR_RNE)
        {
            ulTemp = *SPI_DR;
            ulCount++;
        }

        //
        // Check to see if we can transmit data so that we can receive.
        //
        if(ulTransmitCount <ulLength && (*SPI_SR & SPISR_TNF))
        {
            *SPI_DR = 0;
            ulTransmitCount++;
        }                

        //
        // Have a timeout so the system does not get stuck.
        //
        ullCurrent = GetSystemTimeInUSec();
        if(ullMax < ullCurrent)
        {
            EdbgOutputDebugString("EEINFO: ReadEEWord 1rst Timeout.\r\n");
            return(0);
        }

    } while(ulCount < 4);

    //
    // Read in the rest of the data.
    //
    ullStart    = GetSystemTimeInUSec();
    ullMax      = ullStart + SPI_MINTIME + ulLength * SPI_BYTETIME;
    ulCount     = 0;
    do
    {
        //
        // Check to see if there are bytes to receive.
        //
        if(*SPI_SR & SPISR_RNE)
        {
            pucData[ulCount++] = (UCHAR)(*SPI_DR & 0xFF);
        }

        //
        // Check to see if we can transmit data so that we can receive.
        //
        if(ulTransmitCount <ulLength && (*SPI_SR & SPISR_TNF))
        {
            *SPI_DR = 0;
            ulTransmitCount++;
        }                

        //
        // Have a timeout so the system does not get stuck.
        //
        ullCurrent = GetSystemTimeInUSec();
        if(ullMax < ullCurrent)
        {
            EdbgOutputDebugString("EEINFO: ReadEEWord 2nd Timeout.\r\n");
            EdbgOutputDebugString("EEINFO: Receive = 0x%x, Transmit = 0x%x.\r\n", ulCount, ulTransmitCount);
            return(0);
        }
    } while(ulCount < ulLength);
    return (1);
}


//****************************************************************************
// ClearReceiveFifo
//****************************************************************************
// Clears the Transmit and receive fifo so that the next transaction
// does't get any of the last transactions data.
// 
//  1 - Success 
//  0 - Fail
//
static BOOL ClearReceiveFifo(void)
{
    ULONG ulTemp;
    ULONGLONG ullStart, ullCurrent, ullMax;
    
    //
    // Clear the transmit fifo.
    //
    ullStart = GetSystemTimeInUSec();
    ullMax   = ullStart + SPI_MINTIME;
    while( !(*SPI_SR & SPISR_TFE))
    {
        //
        // Check to see if we timed out.
        //
        ullCurrent = GetSystemTimeInUSec();
        if(ullMax < ullCurrent)
        {
            return(0);
        }
    }

    //
    // Make sure that data is not actively going out.
    //
    ullStart = GetSystemTimeInUSec();
    ullMax   = ullStart + SPI_MINTIME;
    while( *SPI_SR & SPISR_BUSY)
    {
        //
        // Check to see if we timed out.
        //
        ullCurrent = GetSystemTimeInUSec();
        if(ullMax < ullCurrent)
        {
            return(0);
        }
    }

    //
    // Delay 200 uS. Just to make sure that the data is cleared 
    // out the fifo.
    //
    DelayInuSec(200);

    //
    // Read in all of the data that is in the fifo.
    //
    ullStart = GetSystemTimeInUSec();
    ullMax   = ullStart + SPI_MINTIME;
    while( *SPI_SR & SPISR_RNE)
    {
        ulTemp = *SPI_DR;
        //
        // Check to see if we timed out.
        //
        ullCurrent = GetSystemTimeInUSec();
        if(ullMax < ullCurrent)
        {
            return(0);
        }
    }
    return(1);
}


//****************************************************************************
// WaitTillTransmitFifoEmpty
//****************************************************************************
// Clears the Transmit  fifo so that the next transaction
// does't get any of the last transactions data.
// 
//  1 - Success 
//  0 - Fail
//
static BOOL WaitTillTransmitFifoEmpty(void)
{
    ULONGLONG ullStart, ullCurrent, ullMax;
    
    //
    // Clear the transmit fifo.
    //
    ullStart = GetSystemTimeInUSec();
    ullMax   = ullStart + SPI_MINTIME;
    while( !(*SPI_SR & SPISR_TFE))
    {
        //
        // Check to see if we timed out.
        //
        ullCurrent = GetSystemTimeInUSec();
        if(ullMax < ullCurrent)
        {
            return(0);
        }
    }

    //
    // Make sure that data is not actively going out.
    //
    ullStart = GetSystemTimeInUSec();
    ullMax   = ullStart + SPI_MINTIME;
    while( *SPI_SR & SPISR_BUSY)
    {
        //
        // Check to see if we timed out.
        //
        ullCurrent = GetSystemTimeInUSec();
        if(ullMax < ullCurrent)
        {
            return(0);
        }
    }

    //
    // Delay 200 uS. Just to make sure that the data is cleared 
    // out the fifo.
    //
    DelayInuSec(200);

    return(1);
}

⌨️ 快捷键说明

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