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   : AVR 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 "avr/io.h"
    00021 #include "global.h"
    00022
    00023 // library includes
    00024 #include "spi.h"
    00025 #include "spiflash.h"
    00026
    00027 #define SPIFLASH_CONFIG_CS      DDRB  |= (1<<0)
    00028 #define SPIFLASH_ASSERT_CS      PORTB &= (1<<0)
    00029 #define SPIFLASH_RELEASE_CS     PORTB |= (1<<0)
    00030
    00031 // functions
    00032 void spiflashInit(void)
    00033 {
    00034     // initialize spi
    00035     spiInit();
    00036     // initialize chip select
    00037     SPIFLASH_RELEASE_CS;
    00038     SPIFLASH_CONFIG_CS;
    00039 }
    00040
    00041 unsigned short spiflashGetID(void)
    00042 {
    00043     unsigned short id;
    00044
    00045     SPIFLASH_ASSERT_CS;
    00046     spiByte(0, SPIFLASH_CMD_RDID, 0);
    00047     id  = spiByte(0, 0x00, 0)<<8;
    00048     id |= spiByte(0, 0x00, 1);
    00049     SPIFLASH_RELEASE_CS;
    00050
    00051     return id;
    00052 }
    00053
    00054 void spiflashChipErase(void)
    00055 {
    00056     // enable write
    00057     SPIFLASH_ASSERT_CS;
    00058     spiByte(0, SPIFLASH_CMD_WREN, 1);
    00059     SPIFLASH_RELEASE_CS;
    00060
    00061     // clock out dummy byte to waste time
    00062     spiByte(0, 0x00, 1);
    00063
    00064     // do chip erase
    00065     SPIFLASH_ASSERT_CS;
    00066     spiByte(0, SPIFLASH_CMD_CHIPERASE, 1);
    00067     SPIFLASH_RELEASE_CS;
    00068
    00069     // clock out dummy byte to waste time
    00070     spiByte(0, 0x00, 1);
    00071
    00072     // wait until write is done
    00073     SPIFLASH_ASSERT_CS;
    00074     spiByte(0, SPIFLASH_CMD_RDSR, 0);
    00075     while(spiByte(0, 0x00, 0) & SPIFLASH_STATUS_BUSY);
    00076     SPIFLASH_RELEASE_CS;
    00077 }
    00078
    00079 void spiflashRead(unsigned long addr, unsigned long nbytes, unsigned char *data)
    00080 {
    00081     // begin read
    00082     SPIFLASH_ASSERT_CS;
    00083     // issue read command
    00084     spiByte(0, SPIFLASH_CMD_READ, 0);
    00085     // send address
    00086     spiByte(0, addr>>16, 0);
    00087     spiByte(0, addr>>8, 0);
    00088     spiByte(0, addr>>0, 0);
    00089     // read data
    00090     while(nbytes--)
    00091         *data++ = spiByte(0, 0x00, 0);
    00092     // end read
    00093     SPIFLASH_RELEASE_CS;
    00094 }
    00095
    00096 void spiflashWrite(unsigned long addr, unsigned long nbytes, unsigned char *data)
    00097 {
    00098     unsigned int page;
    00099     unsigned int i;
    00100     unsigned int pagelen;
    00101
    00102     // loop through pages to be programmed
    00103     for(page=0; page<((nbytes+SPIFLASH_PAGESIZE-1)>>8); page++)
    00104     {
    00105         // program this page
    00106
    00107         // enable write
    00108         SPIFLASH_ASSERT_CS;
    00109         spiByte(0, SPIFLASH_CMD_WREN, 1);
    00110         SPIFLASH_RELEASE_CS;
    00111
    00112         // clock out dummy byte to waste time
    00113         spiByte(0, 0x00, 1);
    00114
    00115         // begin write
    00116         SPIFLASH_ASSERT_CS;
    00117         // issue write command
    00118         spiByte(0, SPIFLASH_CMD_PAGEPROG, 0);
    00119         // send address
    00120         spiByte(0, addr>>16, 0);
    00121         spiByte(0, addr>>8, 0);
    00122         spiByte(0, addr>>0, 0);
    00123         // program exactly the number of bytes requested
    00124         if( ((page<<8)+SPIFLASH_PAGESIZE) <= nbytes)
    00125             pagelen = SPIFLASH_PAGESIZE;
    00126         else
    00127             pagelen = nbytes-(page<<8);
    00128         // transfer data
    00129         for(i=0; i<pagelen; i++)
    00130             spiByte(0, *data++, 0);
    00131         // end write
    00132         SPIFLASH_RELEASE_CS;
    00133
    00134         // clock out dummy byte to waste time
    00135         spiByte(0, 0x00, 1);
    00136
    00137         // wait until write is done
    00138         SPIFLASH_ASSERT_CS;
    00139         spiByte(0, SPIFLASH_CMD_RDSR, 0);
    00140         while(spiByte(0, 0x00, 0) & SPIFLASH_STATUS_BUSY);
    00141         SPIFLASH_RELEASE_CS;
    00142
    00143         // clock out dummy byte to waste time
    00144         spiByte(0, 0x00, 1);
    00145     }
    00146 }