/home/mooz/bin/arduino-0009/lib/targets/libraries/at45db161d/at45db161d.cpp

Go to the documentation of this file.
00001 #include "at45db161d.h"
00002 
00004 ATD45DB161D::ATD45DB161D()
00005 {}
00007 ATD45DB161D::~ATD45DB161D()
00008 {}
00009 
00011 void ATD45DB161D::Init()
00012 {
00013         uint8_t clr;
00014         
00015         /* Initialize pinout */
00016         pinMode(DATAOUT, OUTPUT);
00017         pinMode(DATAIN, INPUT);
00018         pinMode(SPICLOCK, OUTPUT);
00019         pinMode(SLAVESELECT, OUTPUT);
00020         pinMode(DATAIN, INPUT);
00021   
00022         /* Disable device */
00023         DF_CS_inactive;
00024   
00025         /* Setup SPI */
00026         SPCR = (1 << SPE) | (1 << MSTR) | (1 << CPOL) | (1 << CPHA);
00027 
00028         /* Cleanup registers */
00029         clr = SPSR;
00030         clr = SPDR;
00031 }
00032 
00037 uint8_t ATD45DB161D::ReadStatusRegister()
00038 {
00039         uint8_t status;
00040 
00041         DF_CS_inactive;    /* Make sure to toggle CS signal in order */
00042         DF_CS_active;      /* to reset Dataflash command decoder     */
00043   
00044     /* Send status read command */
00045         spi_transfer(AT45DB161D_STATUS_REGISTER_READ);
00046         /* Get result with a dummy write */
00047         status = spi_transfer(0x00);
00048 
00049         return status;
00050 }
00051 
00059 void ATD45DB161D::ReadManufacturerAndDeviceID(struct ATD45DB161D::ID *id)
00060 {
00061         
00062         DF_CS_inactive;    /* Make sure to toggle CS signal in order */
00063         DF_CS_active;      /* to reset Dataflash command decoder     */
00064   
00065     /* Send status read command */
00066         spi_transfer(AT45DB161D_READ_MANUFACTURER_AND_DEVICE_ID);
00067 
00068         /* Manufacturer ID */
00069         id->manufacturer = spi_transfer(0xff);
00070         /* Device ID (part 1) */
00071         id->device[0] = spi_transfer(0xff);
00072         /* Device ID (part 2) */
00073         id->device[1] = spi_transfer(0xff);
00074         /* Extended Device Information String Length */
00075         id->extendedInfoLength = spi_transfer(0xff);
00076         
00077 }
00078 
00088 void ATD45DB161D::ReadMainMemoryPage(uint16_t page, uint16_t offset)
00089 {
00090         DF_CS_inactive;    /* Make sure to toggle CS signal in order */
00091         DF_CS_active;      /* to reset Dataflash command decoder     */
00092 
00093         /* Send opcode */
00094         spi_transfer(AT45DB161D_PAGE_READ);
00095         
00096         /* Address (page | offset)  */
00097         spi_transfer((uint8_t)(page >> 6));
00098         spi_transfer((uint8_t)((page << 2) | (offset >> 8)));
00099         spi_transfer((uint8_t)(offset & 0xff));
00100         
00101         /* 4 "don't care" bytes */
00102         spi_transfer(0x00);
00103         spi_transfer(0x00);
00104         spi_transfer(0x00);
00105         spi_transfer(0x00);
00106 }
00107 
00116 void ATD45DB161D::ContinuousArrayRead(uint16_t page, uint16_t offset, uint8_t low)
00117 {
00118         DF_CS_inactive;    /* Make sure to toggle CS signal in order */
00119         DF_CS_active;      /* to reset Dataflash command decoder     */
00120 
00121         /* Send opcode */
00122         spi_transfer( low ? AT45DB161D_CONTINUOUS_READ_LOW_FREQ :
00123                             AT45DB161D_CONTINUOUS_READ_HIGH_FREQ );
00124 
00125         /* Address (page | offset)  */
00126         spi_transfer((uint8_t)(page >> 6));
00127         spi_transfer((uint8_t)((page << 2) | (offset >> 8)));
00128         spi_transfer((uint8_t)(offset & 0xff));
00129 }
00130 
00131 
00138 void ATD45DB161D::BufferRead(uint8_t bufferNum, uint16_t offset, uint8_t low)
00139 {
00140         DF_CS_inactive;    /* Make sure to toggle CS signal in order */
00141         DF_CS_active;      /* to reset Dataflash command decoder     */
00142 
00143         /* Send opcode */
00144         if(bufferNum == 1)
00145         {
00146                 spi_transfer(low ? AT45DB161D_BUFFER_1_READ_LOW_FREQ :
00147                                    AT45DB161D_BUFFER_1_READ);
00148         }
00149         else
00150         {
00151                 spi_transfer(low ? AT45DB161D_BUFFER_2_READ_LOW_FREQ :
00152                                    AT45DB161D_BUFFER_2_READ);
00153 
00154         }
00155         
00156         /* 14 "Don't care" bits */
00157         spi_transfer(0x00);
00158         /* Rest of the "don't care" bits + bits 8,9 of the offset */
00159         spi_transfer((uint8_t)(offset >> 8));
00160         /* bits 7-0 of the offset */
00161         spi_transfer((uint8_t)(offset & 0xff));
00162 }
00163 
00173 void ATD45DB161D::BufferWrite(uint8_t bufferNum, uint16_t offset)
00174 {
00175         DF_CS_inactive;    /* Make sure to toggle CS signal in order */
00176         DF_CS_active;      /* to reset Dataflash command decoder     */
00177 
00178         spi_transfer( (bufferNum == 1) ? AT45DB161D_BUFFER_1_WRITE :
00179                                          AT45DB161D_BUFFER_2_WRITE);
00180         
00181         /* 14 "Don't care" bits */
00182         spi_transfer(0x00);
00183         /* Rest of the "don't care" bits + bits 8,9 of the offset */
00184         spi_transfer((uint8_t)(offset >> 8));
00185         /* bits 7-0 of the offset */
00186         spi_transfer((uint8_t)(offset & 0xff));
00187 }
00188 
00196 void ATD45DB161D::BufferToPage(uint8_t bufferNum, uint16_t page, uint8_t erase)
00197 {
00198         DF_CS_inactive;    /* Make sure to toggle CS signal in order */
00199         DF_CS_active;      /* to reset Dataflash command decoder     */
00200 
00201         /* Opcode */
00202         if(erase)
00203         {
00204                 spi_transfer( (bufferNum == 1) ? AT45DB161D_BUFFER_1_TO_PAGE_WITH_ERASE :
00205                                              AT45DB161D_BUFFER_2_TO_PAGE_WITH_ERASE);
00206         }
00207         else
00208         {
00209                 spi_transfer( (bufferNum == 1) ? AT45DB161D_BUFFER_1_TO_PAGE_WITHOUT_ERASE :
00210                                              AT45DB161D_BUFFER_2_TO_PAGE_WITHOUT_ERASE);
00211         }
00212         
00213         /*
00214          * 3 address bytes consist of :
00215          *     - 2 don’t care bits
00216          *     - 12 page address bits (PA11 - PA0) that specify the page in 
00217          *       the main memory to be written
00218          *     - 10 don’t care bits
00219          */
00220         spi_transfer((uint8_t)(page >> 6));
00221         spi_transfer((uint8_t)(page << 2));
00222         spi_transfer(0x00);
00223         
00224         DF_CS_inactive;  /* Start transfer */
00225         DF_CS_active;    /* If erase was set, the page will first be erased */
00226 
00227         /* Wait for the end of the transfer */
00228         while(!(ReadStatusRegister() & READY_BUSY))
00229         {}
00230 }
00231 
00237 void ATD45DB161D::PageToBuffer(uint16_t page, uint8_t bufferNum)
00238 {
00239         DF_CS_inactive;    /* Make sure to toggle CS signal in order */
00240         DF_CS_active;      /* to reset Dataflash command decoder     */
00241  
00242         /* Send opcode */
00243         spi_transfer((bufferNum == 1) ? AT45DB161D_TRANSFER_PAGE_TO_BUFFER_1 :
00244                                         AT45DB161D_TRANSFER_PAGE_TO_BUFFER_2);
00245 
00246         /*
00247          * 3 address bytes consist of :
00248          *     - 2 don’t care bits
00249          *     - 12 page address bits (PA11 - PA0) that specify the page in 
00250          *       the main memory to be written
00251          *     - 10 don’t care bits
00252          */
00253         spi_transfer((uint8_t)(page >> 6));
00254         spi_transfer((uint8_t)(page << 2));
00255         spi_transfer(0x00);
00256                 
00257         DF_CS_inactive;  /* Start page transfer */
00258         DF_CS_active;
00259 
00260         /* Wait for the end of the transfer */
00261         while(!(ReadStatusRegister() & READY_BUSY))
00262         {}
00263 }
00264 
00269 void ATD45DB161D::PageErase(uint16_t page)
00270 {
00271         DF_CS_inactive;    /* Make sure to toggle CS signal in order */
00272         DF_CS_active;      /* to reset Dataflash command decoder     */
00273 
00274         /* Send opcode */
00275         spi_transfer(AT45DB161D_PAGE_ERASE);
00276         
00277         /*
00278          * 3 address bytes consist of :
00279          *     - 2 don’t care bits
00280          *     - 12 page address bits (PA11 - PA0) that specify the page in 
00281          *       the main memory to be written
00282          *     - 10 don’t care bits
00283          */
00284         spi_transfer((uint8_t)(page >> 6));
00285         spi_transfer((uint8_t)(page << 2));
00286         spi_transfer(0x00);
00287                 
00288         DF_CS_inactive;  /* Start block erase */
00289         DF_CS_active;
00290 
00291         /* Wait for the end of the block erase operation */
00292         while(!(ReadStatusRegister() & READY_BUSY))
00293         {}
00294 }
00295 
00300 void ATD45DB161D::BlockErase(uint16_t block)
00301 {
00302         DF_CS_inactive;    /* Make sure to toggle CS signal in order */
00303         DF_CS_active;      /* to reset Dataflash command decoder     */
00304 
00305         /* Send opcode */
00306         spi_transfer(AT45DB161D_BLOCK_ERASE);
00307         
00308         /*
00309          * 3 address bytes consist of :
00310          *     - 2 don’t care bits
00311          *     - 9 block address bits (PA11 - PA3)
00312          *     - 13 don’t care bits
00313          */
00314         spi_transfer((uint8_t)(block >> 3));
00315         spi_transfer((uint8_t)(block << 5));
00316         spi_transfer(0x00);
00317                 
00318         DF_CS_inactive;  /* Start block erase */
00319         DF_CS_active;
00320 
00321         /* Wait for the end of the block erase operation */
00322         while(!(ReadStatusRegister() & READY_BUSY))
00323         {}
00324 }
00325 
00331 void ATD45DB161D::SectoreErase(uint8_t sector)
00332 {
00333         DF_CS_inactive;    /* Make sure to toggle CS signal in order */
00334         DF_CS_active;      /* to reset Dataflash command decoder     */
00335 
00336         /* Send opcode */
00337         spi_transfer(AT45DB161D_SECTOR_ERASE);
00338         
00339         /*
00340          * 3 address bytes consist of :
00341          */
00342         if((sector == 0x0a) || (sector == 0x0b))
00343         {
00344                 /*
00345                  *  - 11 don’t care bits
00346                  *  - 
00347                  *  - 12 don’t care bits
00348                  */
00349                 spi_transfer(0x00);
00350                 spi_transfer(((sector & 0x01) << 4));
00351                 spi_transfer(0x00);
00352         }
00353         else
00354         {
00355                 /*
00356                  *  - 2 don't care bits 
00357                  *  - 4 sector number bits
00358                  *  - 18 don't care bits 
00359                  */
00360                 spi_transfer(sector << 1);
00361                 spi_transfer(0x00);
00362                 spi_transfer(0x00);
00363         }
00364                                 
00365         DF_CS_inactive;  /* Start block erase */
00366         DF_CS_active;
00367 
00368         /* Wait for the end of the block erase operation */
00369         while(!(ReadStatusRegister() & READY_BUSY))
00370         {}
00371 }
00372 
00377 void ATD45DB161D::ChipErase()
00378 {
00379         DF_CS_inactive;    /* Make sure to toggle CS signal in order */
00380         DF_CS_active;      /* to reset Dataflash command decoder     */
00381 
00382         /* Send chip erase sequence */
00383         spi_transfer(AT45DB161D_CHIP_ERASE_0);
00384         spi_transfer(AT45DB161D_CHIP_ERASE_1);
00385         spi_transfer(AT45DB161D_CHIP_ERASE_2);
00386         spi_transfer(AT45DB161D_CHIP_ERASE_3);
00387                                 
00388         DF_CS_inactive;  /* Start chip erase */
00389         DF_CS_active;
00390 
00391         /* Wait for the end of the chip erase operation */
00392         while(!(ReadStatusRegister() & READY_BUSY))
00393         {}
00394 }
00395 
00405 void ATD45DB161D::BeginPageWriteThroughBuffer(uint16_t page, uint16_t offset, uint8_t bufferNum)
00406 {
00407         DF_CS_inactive;    /* Make sure to toggle CS signal in order */
00408         DF_CS_active;      /* to reset Dataflash command decoder     */
00409 
00410         /* Send opcode */
00411         spi_transfer((bufferNum == 1) ? AT45DB161D_PAGE_THROUGH_BUFFER_1 :
00412                                         AT45DB161D_PAGE_THROUGH_BUFFER_2);
00413 
00414         /* Address */
00415         spi_transfer((uint8_t)(page >> 6));
00416         spi_transfer((uint8_t)((page << 2) | (offset >> 8)));
00417         spi_transfer((uint8_t)offset);
00418 }
00419 
00424 void ATD45DB161D::EndAndWait()
00425 {
00426         DF_CS_inactive;  /* End current operation */
00427         DF_CS_active;    /* Some internal operation may occur
00428                           * (buffer to page transfer, page erase, etc... ) */
00429 
00430         /* Wait for the chip to be ready */
00431         while(!(ReadStatusRegister() & READY_BUSY))
00432         {}
00433 }
00434 
00444 int8_t ATD45DB161D::ComparePageToBuffer(uint16_t page, uint8_t bufferNum)
00445 {
00446         uint8_t status;
00447         
00448         DF_CS_inactive;    /* Make sure to toggle CS signal in order */
00449         DF_CS_active;      /* to reset Dataflash command decoder     */
00450 
00451         /* Send opcode */
00452         spi_transfer((bufferNum == 1) ? AT45DB161D_COMPARE_PAGE_TO_BUFFER_1 :
00453                                         AT45DB161D_COMPARE_PAGE_TO_BUFFER_2);
00454         
00455         /* Page address */
00456         spi_transfer((uint8_t)(page >> 6));
00457         spi_transfer((uint8_t)(page << 2));
00458         spi_transfer(0x00);
00459         
00460         DF_CS_inactive;  /* Start comparaison */
00461         DF_CS_active;
00462 
00463         /* Wait for the end of the comparaison and get the result */
00464         while(!((status = ReadStatusRegister()) & READY_BUSY))
00465         {}
00466                 
00467         return ((status & COMPARE) == COMPARE);
00468 }
00469 
00477 void ATD45DB161D::DeepPowerDown()
00478 {
00479         DF_CS_inactive;    /* Make sure to toggle CS signal in order */
00480         DF_CS_active;      /* to reset Dataflash command decoder     */
00481         
00482         /* Send opcode */
00483         spi_transfer(AT45DB161D_DEEP_POWER_DOWN);
00484         
00485         /* Enter Deep Power-Down mode */
00486         DF_CS_inactive;
00487         
00488         /* Safety delay */
00489         delay(100);
00490 }
00491 
00495 void ATD45DB161D::ResumeFromDeepPowerDown()
00496 {
00497         DF_CS_inactive;    /* Make sure to toggle CS signal in order */
00498         DF_CS_active;      /* to reset Dataflash command decoder     */
00499         
00500         /* Send opcode */
00501         spi_transfer(AT45DB161D_RESUME_FROM_DEEP_POWER_DOWN);
00502         
00503         /* Resume device */
00504         DF_CS_inactive;
00505         
00506         /* The CS pin must stay high during t_RDPD microseconds before the device
00507          * can receive any commands.
00508          * On the at45db161D t_RDPD = 35 microseconds. But we will wait 100
00509          * (just to be sure). */
00510         delay(100);
00511 }
00512  

Generated on Sun Oct 21 18:24:47 2007 for at45db161d by  doxygen 1.5.2