📄 eeinfo.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 + -