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 }

Generated on Sun Oct 29 03:41:07 2006 for Procyon AVRlib by  doxygen 1.4.2