Main Page | Modules | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

# spiflash.c

Go to the documentation of this file.

    00001 /*! \file spiflash.c \brief SPI Flash Memory Driver (M25Pxx/AT25Fxxx/etc). */
    00002 //*****************************************************************************
    00003 //
    00004 // File Name    : 'spiflash.c'
    00005 // Title        : SPI Flash Memory Driver (M25Pxx/AT25Fxxx/etc)
    00006 // Author       : Pascal Stang - Copyright (C) 2006
    00007 // Created      : 2006-04-15
    00008 // Revised      : 2006-07-02
    00009 // Version      : 0.1
    00010 // Target MCU   : ARM processors
    00011 // Editor Tabs  : 4
    00012 //
    00013 // NOTE: This code is currently below version 1.0, and therefore is considered
    00014 // to be lacking in some functionality or documentation, or may not be fully
    00015 // tested.  Nonetheless, you can expect most functions to work.
    00016 //
    00017 //*****************************************************************************
    00018
    00019 // system includes
    00020 #include "at91sam7s64.h"
    00021 #include "global.h"
    00022
    00023 // local includes
    00024 #include "spi.h"
    00025 #include "spiflash.h"
    00026 /*
    00027 #define SPIFLASH_CONFIG_CS      AT91C_BASE_PIOA->PIO_PER = AT91C_PIO_PA11; \
    00028                                 AT91C_BASE_PIOA->PIO_OER = AT91C_PIO_PA11
    00029 #define SPIFLASH_ASSERT_CS      AT91C_BASE_PIOA->PIO_CODR = AT91C_PIO_PA11
    00030 #define SPIFLASH_RELEASE_CS     AT91C_BASE_PIOA->PIO_SODR = AT91C_PIO_PA11
    00031 */
    00032
    00033 #define SPIFLASH_CONFIG_CS      AT91C_BASE_PIOA->PIO_PER = AT91C_PIO_PA30; \
    00034                                 AT91C_BASE_PIOA->PIO_OER = AT91C_PIO_PA30
    00035 #define SPIFLASH_ASSERT_CS      AT91C_BASE_PIOA->PIO_CODR = AT91C_PIO_PA30
    00036 #define SPIFLASH_RELEASE_CS     AT91C_BASE_PIOA->PIO_SODR = AT91C_PIO_PA30
    00037
    00038 // functions
    00039 void spiflashInit(void)
    00040 {
    00041     // initialize spi
    00042     //spiInit();
    00043     // initialize chip select
    00044     SPIFLASH_RELEASE_CS;
    00045     SPIFLASH_CONFIG_CS;
    00046 }
    00047
    00048 unsigned short spiflashGetID(void)
    00049 {
    00050     unsigned short id;
    00051
    00052     SPIFLASH_ASSERT_CS;
    00053     spiTransferByte(SPIFLASH_CMD_RDID);
    00054     id  = spiTransferByte(0x00)<<8;
    00055     id |= spiTransferByte(0x00);
    00056     SPIFLASH_RELEASE_CS;
    00057
    00058     return id;
    00059 }
    00060
    00061 void spiflashChipErase(void)
    00062 {
    00063     // enable write
    00064     SPIFLASH_ASSERT_CS;
    00065     spiTransferByte(SPIFLASH_CMD_WREN);
    00066     SPIFLASH_RELEASE_CS;
    00067
    00068     // clock out dummy byte to waste time
    00069     spiTransferByte(0x00);
    00070
    00071     // do chip erase
    00072     SPIFLASH_ASSERT_CS;
    00073     spiTransferByte(SPIFLASH_CMD_CHIPERASE);
    00074     SPIFLASH_RELEASE_CS;
    00075
    00076     // clock out dummy byte to waste time
    00077     spiTransferByte(0x00);
    00078
    00079     // wait until write is done
    00080     SPIFLASH_ASSERT_CS;
    00081     spiTransferByte(SPIFLASH_CMD_RDSR);
    00082     while(spiTransferByte(0x00) & SPIFLASH_STATUS_BUSY);
    00083     SPIFLASH_RELEASE_CS;
    00084 }
    00085
    00086 void spiflashRead(unsigned long addr, unsigned long nbytes, unsigned char *data)
    00087 {
    00088     // begin read
    00089     SPIFLASH_ASSERT_CS;
    00090     // issue read command
    00091     spiTransferByte(SPIFLASH_CMD_READ);
    00092     // send address
    00093     spiTransferByte(addr>>16);
    00094     spiTransferByte(addr>>8);
    00095     spiTransferByte(addr>>0);
    00096     // read data
    00097     while(nbytes--)
    00098         *data++ = spiTransferByte(0x00);
    00099     // end read
    00100     SPIFLASH_RELEASE_CS;
    00101 }
    00102
    00103 void spiflashWrite(unsigned long addr, unsigned long nbytes, unsigned char *data)
    00104 {
    00105     unsigned int page;
    00106     unsigned int i;
    00107     unsigned int pagelen;
    00108
    00109     // loop through pages to be programmed
    00110     for(page=0; page<((nbytes+SPIFLASH_PAGESIZE-1)>>8); page++)
    00111     {
    00112         // program this page
    00113
    00114         // enable write
    00115         SPIFLASH_ASSERT_CS;
    00116         spiTransferByte(SPIFLASH_CMD_WREN);
    00117         SPIFLASH_RELEASE_CS;
    00118
    00119         // clock out dummy byte to waste time
    00120         spiTransferByte(0x00);
    00121
    00122         // begin write
    00123         SPIFLASH_ASSERT_CS;
    00124         // issue write command
    00125         spiTransferByte(SPIFLASH_CMD_PAGEPROG);
    00126         // send address
    00127         spiTransferByte(addr>>16);
    00128         spiTransferByte(addr>>8);
    00129         spiTransferByte(addr>>0);
    00130         // program exactly the number of bytes requested
    00131         if( ((page<<8)+SPIFLASH_PAGESIZE) <= nbytes)
    00132             pagelen = SPIFLASH_PAGESIZE;
    00133         else
    00134             pagelen = nbytes-(page<<8);
    00135         // transfer data
    00136         for(i=0; i<pagelen; i++)
    00137             spiTransferByte(*data++);
    00138         // end write
    00139         SPIFLASH_RELEASE_CS;
    00140
    00141         // clock out dummy byte to waste time
    00142         spiTransferByte(0x00);
    00143
    00144         // wait until write is done
    00145         SPIFLASH_ASSERT_CS;
    00146         spiTransferByte(SPIFLASH_CMD_RDSR);
    00147         while(spiTransferByte(0x00) & SPIFLASH_STATUS_BUSY);
    00148         SPIFLASH_RELEASE_CS;
    00149
    00150         // clock out dummy byte to waste time
    00151         spiTransferByte(0x00);
    00152     }
    00153 }