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

📄 m25p80.txt

📁 利用SPI模块读写串行FLASH(M25P80)的程序
💻 TXT
字号:
// ----------------------------------------------------------------------
//	THIS CODE OF FOR AN ST-M25P80MW SERIAL EEPROM
//
//  The memory contains 8 sectors of 256 pages of 256 bytes
//
//  Chip and sector erase are supported.
//
//  The device can operate at 25Mhz SPI speed.
//	Special grade 6 device can operate at 40Mhz
//
//  The chip select line:
//	min 10ns. before clock starts
//	min 100ns. for deselects
//
//
//
//
//
// ----------------------------------------------------------------------
#include <sys\exception.h>
#include <cdefBF532.h>


#include "spi_memory.h"

// ----------------------------------------------------------------------
//  Chip select pin
#define SPIMEM_CHIPSELECT	(0x0004)
//  Chip command bytes
#define SPIMEM_WREN        (0x06)
#define SPIMEM_WRDI        (0x04)
#define SPIMEM_RDSR        (0x05)
#define SPIMEM_WRSR        (0x01)
#define SPIMEM_READSLOW    (0x03)
#define SPIMEM_READFAST    (0x0B)	//  not implemented
#define SPIMEM_BYTEPROGRAM (0x02)
#define SPIMEM_SECTORERASE (0xd8)
#define SPIMEM_CHIPERASE   (0xc7)

#define SPIMEM_DP          (0xb9)
#define SPIMEM_RES         (0xab)

// ----------------------------------------------------------------------
void PROM_WRITE (unsigned char data)
{
unsigned short SPI;

// Send the data
  *pSPI_TDBR = data;
// Wait for TX to complete
  SPI = *pSPI_STAT;
  while (SPI&0x0008)
    {
      SPI = *pSPI_STAT;
    }
//  Wait for RX to complete
  while (!(SPI & 0x20))
    {
      SPI = *pSPI_STAT;
    }
//  Clear the RX buffer
  data = *pSPI_RDBR;
}

// ----------------------------------------------------------------------
unsigned char PROM_READ (void)
{
unsigned short SPI;
unsigned char data;

//  Send a null byte
  *pSPI_TDBR = 0x00;
//  Wait for TX to complete
  SPI = *pSPI_STAT;
  while ((SPI&0x0008))
    {
      SPI = *pSPI_STAT;
    }
//  Wait for RX to complete
  while (!(SPI&0x20))
    {
      SPI = *pSPI_STAT;
    }
//  Read the byte
  data = *pSPI_RDBR;
  return data;
}

// ----------------------------------------------------------------------
void select_spi_memory (void)
{
  *pFIO_FLAG_C = SPIMEM_CHIPSELECT;
}

// ----------------------------------------------------------------------
void deselect_spi_memory (void)
{
  *pFIO_FLAG_S = SPIMEM_CHIPSELECT;
}

// ----------------------------------------------------------------------
int spi_open_memory (void)
{
unsigned short SPI;
unsigned short SPI_RECV;
   
//  Setup the SPI port
  *pSPI_BAUD = 4;
  *pSPI_FLG = 0xff00;
  *pSPI_CTL = 0x5029;
//  Setup the chip select flag pin
  *pFIO_DIR |= SPIMEM_CHIPSELECT;
  deselect_spi_memory ();
//  Clear the RX buffer
  SPI = *pSPI_STAT;
  while (SPI&0x20)
    {
      SPI_RECV = *pSPI_RDBR;
      SPI = *pSPI_STAT;
    }
//  Reset the SPI port
  *pSPI_STAT = 0xFF;
//  Send a reset command, also reads the signature
//    Return should be 0x12
   return spi_reset ();
}

// ----------------------------------------------------------------------
int spi_close_memory (void)
{
//  Reset the SPI port
  *pSPI_CTL = 0x0400;
  return 0;
}

// ----------------------------------------------------------------------
unsigned char spi_read_byte (unsigned int address)
{
unsigned char data;

//  Select the memory ship
  select_spi_memory();
//  Send the read command
  PROM_WRITE (SPIMEM_READSLOW); 
//  Send the address
  PROM_WRITE ((address&0x00FF0000)>>16);
  PROM_WRITE ((address&0x0000FF00)>>8);
  PROM_WRITE ((address&0x000000FF));
//  Read a byte
  data = PROM_READ();
  deselect_spi_memory();
  return data;	
}

// ----------------------------------------------------------------------
void spi_write_byte (unsigned int address,
	unsigned char data)
{
unsigned char MEMSTAT;

//  Send the write enable command
  select_spi_memory ();
  PROM_WRITE (SPIMEM_WREN);
  deselect_spi_memory ();
//  Select the chip again
  select_spi_memory ();
//  Byte program command
  PROM_WRITE (SPIMEM_BYTEPROGRAM);
//  Send the address
  PROM_WRITE ((address&0x00FF0000)>>16);
  PROM_WRITE ((address&0x0000FF00)>>8);
  PROM_WRITE ((address&0x000000FF));
//  Send the byte
  PROM_WRITE (data);
//  Complete the command
  deselect_spi_memory ();
//  Poll status until the write completes
  do {
    select_spi_memory ();
    PROM_WRITE (SPIMEM_RDSR);
    MEMSTAT = PROM_READ ();
    deselect_spi_memory ();
    } while (MEMSTAT&0x01);
  return;
}

// ----------------------------------------------------------------------
void spi_chip_erase (void)
{
unsigned short int MEMSTAT;

//  Send the write enable command
  select_spi_memory ();
  PROM_WRITE (SPIMEM_WREN);
  deselect_spi_memory ();
//  Send the chip erase command
  select_spi_memory ();
  PROM_WRITE (SPIMEM_CHIPERASE);
  deselect_spi_memory ();
//  Poll status until erase completes. 4-10 sec.
  do {
    select_spi_memory (); 
    PROM_WRITE (SPIMEM_RDSR);
    MEMSTAT = PROM_READ ();
    deselect_spi_memory ();
    } while (MEMSTAT&0x01);
  return;     
}

// ----------------------------------------------------------------------
void spi_sector_erase (unsigned int address)
{
unsigned char MEMSTAT;
   
//  Send the write enable command
  select_spi_memory ();
  PROM_WRITE (SPIMEM_WREN);
  deselect_spi_memory ();
//  Send the sector erase command
  select_spi_memory();
  PROM_WRITE (SPIMEM_SECTORERASE); 
//  Send the address (any address within the sector)  
  PROM_WRITE ((address&0x00FF0000)>>16);
  PROM_WRITE ((address&0x0000FF00)>>8);
  PROM_WRITE ((address&0x000000FF));
  deselect_spi_memory ();
//  Poll status until erase completes. 4-10 sec.
  do {
    select_spi_memory (); 
    PROM_WRITE (SPIMEM_RDSR);
    MEMSTAT = PROM_READ ();
    deselect_spi_memory ();
    } while (MEMSTAT&0x01);
  return;     
}

// ----------------------------------------------------------------------
unsigned char spi_rdsr (void)
{
unsigned char rdsr;

  select_spi_memory ();
  PROM_WRITE (SPIMEM_RDSR);
  rdsr = PROM_READ ();
  deselect_spi_memory ();
  return rdsr;
}

// ----------------------------------------------------------------------
void spi_wrsr (unsigned char data)
{
unsigned char rdsr;

//  Send the write enable command
  select_spi_memory ();
  PROM_WRITE (SPIMEM_WREN);
  deselect_spi_memory ();
//  Send the write status command and data
  select_spi_memory ();
  PROM_WRITE (SPIMEM_WRSR);
  PROM_WRITE (data);
  deselect_spi_memory ();
  return;
}

// ----------------------------------------------------------------------
void spi_read_block (unsigned int address,
	unsigned char *block, int count)
{
  if (count == 0) return;
//  Send the read slow command
  select_spi_memory ();
  PROM_WRITE (SPIMEM_READSLOW);
//  Send the address
  PROM_WRITE ((address&0x00FF0000)>>16);
  PROM_WRITE ((address&0x0000FF00)>>8);
  PROM_WRITE ((address&0x000000FF));
//  Read number of bytes
  while (count)
    {
      *block = PROM_READ ();
      block++;
      count--;
    }
  deselect_spi_memory ();
  return;
}

// ----------------------------------------------------------------------
void spi_write_block (unsigned int address,
	unsigned char *block, int count)
{
unsigned char MEMSTAT;

  while (count)
    {
//  Send a write enable command
      select_spi_memory ();
      PROM_WRITE (SPIMEM_WREN);
      deselect_spi_memory ();
//  Send a page program command
      select_spi_memory();
      PROM_WRITE (SPIMEM_BYTEPROGRAM); 
//  Send the address
      PROM_WRITE ((address&0x00FF0000)>>16);
      PROM_WRITE ((address&0x0000FF00)>>8);
      PROM_WRITE ((address&0x000000FF));
//  Send at least one byte
      PROM_WRITE (*block);
//  Increment 
      count--;
      address++;
      block++;
//  Send bytes until we get to the end of a page
      while ((count > 0) && ((address&0x0000ff) != 0))
	{
	  PROM_WRITE (*block);
	  count--;
	  address++;
	  block++;
	}
//  Deselect the chip
      deselect_spi_memory();
//  Poll status until the write completes
      do {
        select_spi_memory ();
        PROM_WRITE (SPIMEM_RDSR);
        MEMSTAT = PROM_READ ();
        deselect_spi_memory ();
        } while (MEMSTAT&0x01);
    }
}

// ----------------------------------------------------------------------
void spi_deeppowerdown (void)
{
//  Send the deep power down command
  select_spi_memory ();
  PROM_WRITE (SPIMEM_DP);
  deselect_spi_memory ();
}
// ----------------------------------------------------------------------
unsigned char spi_reset (void)
{
unsigned char data;

//  Send the reset command
  select_spi_memory ();
  PROM_WRITE (SPIMEM_RES);
//  Three dummy bytes
  PROM_WRITE (0);
  PROM_WRITE (0);
  PROM_WRITE (0);
//  Read the Electronic Signature
  data = PROM_READ ();
  deselect_spi_memory ();
  return data;
}
// ----------------------------------------------------------------------

⌨️ 快捷键说明

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