Smart-Home am Beispiel der Präsenzerkennung im Raum Projektarbeit Lennart Heimbs, Johannes Krug, Sebastian Dohle und Kevin Holzschuh bei Prof. Oliver Hofmann SS2019
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

SPIFlash.h 8.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. // Copyright (c) 2013-2015 by Felix Rusu, LowPowerLab.com
  2. // SPI Flash memory library for arduino/moteino.
  3. // This works with 256byte/page SPI flash memory
  4. // For instance a 4MBit (512Kbyte) flash chip will have 2048 pages: 256*2048 = 524288 bytes (512Kbytes)
  5. // Minimal modifications should allow chips that have different page size but modifications
  6. // DEPENDS ON: Arduino SPI library
  7. // > Updated Jan. 5, 2015, TomWS1, modified writeBytes to allow blocks > 256 bytes and handle page misalignment.
  8. // > Updated Feb. 26, 2015 TomWS1, added support for SPI Transactions (Arduino 1.5.8 and above)
  9. // > Selective merge by Felix after testing in IDE 1.0.6, 1.6.4
  10. // > Updated May 19, 2016 D-H-R, added support for SST25/Microchip Flash which does not support Page programming with OPCode 0x02,
  11. // > use define MY_SPIFLASH_SST25TYPE for SST25 Type Flash Memory. Added / changed comments to better suit doxygen
  12. // > Updated Sep 07, 2018 tekka, sync with https://github.com/LowPowerLab/SPIFlash
  13. // **********************************************************************************
  14. // License
  15. // **********************************************************************************
  16. // This program is free software; you can redistribute it
  17. // and/or modify it under the terms of the GNU General
  18. // Public License as published by the Free Software
  19. // Foundation; either version 3 of the License, or
  20. // (at your option) any later version.
  21. //
  22. // This program is distributed in the hope that it will
  23. // be useful, but WITHOUT ANY WARRANTY; without even the
  24. // implied warranty of MERCHANTABILITY or FITNESS FOR A
  25. // PARTICULAR PURPOSE. See the GNU General Public
  26. // License for more details.
  27. //
  28. // You should have received a copy of the GNU General
  29. // Public License along with this program.
  30. // If not, see <http://www.gnu.org/licenses/>.
  31. //
  32. // Licence can be viewed at
  33. // http://www.gnu.org/licenses/gpl-3.0.txt
  34. //
  35. // Please maintain this license information along with authorship
  36. // and copyright notices in any redistribution of this code
  37. ///
  38. /// @file SPIFlash.h
  39. ///
  40. /// @brief SPIFlash provides access to a SPI Flash IC for OTA update or storing data
  41. ///
  42. /// IMPORTANT: NAND FLASH memory requires erase before write, because
  43. /// it can only transition from 1s to 0s and only the erase command can reset all 0s to 1s
  44. /// See http://en.wikipedia.org/wiki/Flash_memory
  45. /// The smallest range that can be erased is a sector (4K, 32K, 64K); there is also a chip erase command
  46. ///
  47. /// Standard SPI flash commands <BR>
  48. /// Assuming the WP pin is pulled up (to disable hardware write protection).<BR>
  49. /// To use any write commands the WEL bit in the status register must be set to 1.<BR>
  50. /// This is accomplished by sending a 0x06 command before any such write/erase command.<BR>
  51. /// The WEL bit in the status register resets to the logical ?0? state after a device power-up or reset.
  52. /// In addition, the WEL bit will be reset to the logical ?0? state automatically under the following conditions:<BR>
  53. /// - Write Disable operation completes successfully<BR>
  54. /// - Write Status Register operation completes successfully or aborts<BR>
  55. /// - Protect Sector operation completes successfully or aborts<BR>
  56. /// - Unprotect Sector operation completes successfully or aborts<BR>
  57. /// - Byte/Page Program operation completes successfully or aborts<BR>
  58. /// - Sequential Program Mode reaches highest unprotected memory location<BR>
  59. /// - Sequential Program Mode reaches the end of the memory array<BR>
  60. /// - Sequential Program Mode aborts<BR>
  61. /// - Block Erase operation completes successfully or aborts<BR>
  62. /// - Chip Erase operation completes successfully or aborts<BR>
  63. /// - Hold condition aborts
  64. ///
  65. #ifndef _SPIFLASH_H_
  66. #define _SPIFLASH_H_
  67. #if ARDUINO >= 100
  68. #include <Arduino.h>
  69. #else
  70. #include <wiring.h>
  71. #include "pins_arduino.h"
  72. #endif
  73. #include <SPI.h>
  74. #ifndef SPIFLASH_WRITEENABLE
  75. #define SPIFLASH_WRITEENABLE 0x06 //!< write enable
  76. #endif
  77. #ifndef SPIFLASH_WRITEDISABLE
  78. #define SPIFLASH_WRITEDISABLE 0x04 //!< write disable
  79. #endif
  80. #ifndef SPIFLASH_BLOCKERASE_4K
  81. #define SPIFLASH_BLOCKERASE_4K 0x20 //!< erase one 4K block of flash memory
  82. #endif
  83. #ifndef SPIFLASH_BLOCKERASE_32K
  84. #define SPIFLASH_BLOCKERASE_32K 0x52 //!< erase one 32K block of flash memory
  85. #endif
  86. #ifndef SPIFLASH_BLOCKERASE_64K
  87. #define SPIFLASH_BLOCKERASE_64K 0xD8 //!< erase one 64K block of flash memory
  88. #endif
  89. #ifndef SPIFLASH_CHIPERASE
  90. #define SPIFLASH_CHIPERASE 0x60 //!< @brief chip erase (may take several seconds depending on size)
  91. #endif
  92. //!< Chip is erased but not actually waited for completion (instead need to check the status register BUSY bit)
  93. #ifndef SPIFLASH_STATUSREAD
  94. #define SPIFLASH_STATUSREAD 0x05 //!< read status register
  95. #endif
  96. #ifndef SPIFLASH_STATUSWRITE
  97. #define SPIFLASH_STATUSWRITE 0x01 //!< write status register
  98. #endif
  99. #ifndef SPIFLASH_ARRAYREAD
  100. #define SPIFLASH_ARRAYREAD 0x0B //!< read array (fast, need to add 1 dummy byte after 3 address bytes)
  101. #endif
  102. #ifndef SPIFLASH_ARRAYREADLOWFREQ
  103. #define SPIFLASH_ARRAYREADLOWFREQ 0x03 //!< read array (low frequency)
  104. #endif
  105. #ifndef SPIFLASH_SLEEP
  106. #define SPIFLASH_SLEEP 0xB9 //!< deep power down
  107. #endif
  108. #ifndef SPIFLASH_WAKE
  109. #define SPIFLASH_WAKE 0xAB //!< deep power wake up
  110. #endif
  111. #ifndef SPIFLASH_BYTEPAGEPROGRAM
  112. #define SPIFLASH_BYTEPAGEPROGRAM 0x02 //!< write (1 to 256bytes). Writing more than one Byte is not supported on all devices (e.g. SST25 Series)
  113. #endif
  114. #ifndef SPIFLASH_AAIWORDPROGRAM
  115. #define SPIFLASH_AAIWORDPROGRAM 0xAD //!< @brief Auto Address Increment Programming on Microchip SST Family Devices which do not support page program. <BR>
  116. #endif
  117. //!< Use define #MY_SPIFLASH_SST25TYPE to use AAI prog instead of Bytepageprogram which does not work on SST Family Chips
  118. //!< tested with SST25PF020B80 http://ww1.microchip.com/downloads/en/DeviceDoc/20005135B.pdf
  119. #ifndef SPIFLASH_IDREAD
  120. #define SPIFLASH_IDREAD 0x9F //!< @brief read JEDEC manufacturer and device ID (2 bytes, specific bytes for each manufacturer and device)
  121. #endif
  122. //!< Example for Atmel-Adesto 4Mbit AT25DF041A: 0x1F44 (page 27: http://www.adestotech.com/sites/default/files/datasheets/doc3668.pdf)
  123. //!< Example for Winbond 4Mbit W25X40CL: 0xEF30 (page 14: http://www.winbond.com/NR/rdonlyres/6E25084C-0BFE-4B25-903D-AE10221A0929/0/W25X40CL.pdf)
  124. #ifndef SPIFLASH_MACREAD
  125. #define SPIFLASH_MACREAD 0x4B //!< read unique ID number (MAC)
  126. #endif
  127. ///
  128. /// @def MY_SPIFLASH_SST25TYPE
  129. /// @brief If set AAI Word Programming is used to support SST25 Family SPI Flash.
  130. ///
  131. /// SST25 Family Flash does not support programming multiple Bytes with opcode 0x02 #SPIFLASH_BYTEPAGEPROGRAM. <BR>
  132. /// If SPIFLASH_SST25TYPE is set and writeBytes is called, it will use opcode 0xAD #SPIFLASH_AAIWORDPROGRAM and care for Byte alignment.<BR>
  133. /// Note: AAI Wordprogramming is independent of Pages, so pagebreaking is not an issue when using AAI Wordprogramming.
  134. ///
  135. #ifdef DOXYGEN //needed to tell doxygen not to ignore the define which is actually made somewhere else
  136. #define MY_SPIFLASH_SST25TYPE
  137. #endif
  138. /** SPIFlash class */
  139. class SPIFlash
  140. {
  141. public:
  142. static uint8_t UNIQUEID[8]; //!< Storage for unique identifier
  143. SPIFlash(uint8_t slaveSelectPin, uint16_t jedecID=0); //!< Constructor
  144. bool initialize(); //!< setup SPI, read device ID etc...
  145. void command(uint8_t cmd, bool isWrite=
  146. false); //!< Send a command to the flash chip, pass TRUE for isWrite when its a write command
  147. uint8_t readStatus(); //!< return the STATUS register
  148. uint8_t readByte(uint32_t addr); //!< read 1 byte from flash memory
  149. void readBytes(uint32_t addr, void* buf, uint16_t len); //!< read unlimited # of bytes
  150. void writeByte(uint32_t addr, uint8_t byt); //!< Write 1 byte to flash memory
  151. void writeBytes(uint32_t addr, const void* buf,
  152. uint16_t len); //!< write multiple bytes to flash memory (up to 64K), if define SPIFLASH_SST25TYPE is set AAI Word Programming will be used
  153. bool busy(); //!< check if the chip is busy erasing/writing
  154. void chipErase(); //!< erase entire flash memory array
  155. void blockErase4K(uint32_t address); //!< erase a 4Kbyte block
  156. void blockErase32K(uint32_t address); //!< erase a 32Kbyte block
  157. void blockErase64K(uint32_t addr); //!< erase a 64Kbyte block
  158. uint16_t readDeviceId(); //!< Get the manufacturer and device ID bytes (as a short word)
  159. uint8_t* readUniqueId(); //!< Get the 64 bit unique identifier, stores it in @ref UNIQUEID[8]
  160. void sleep(); //!< Put device to sleep
  161. void wakeup(); //!< Wake device
  162. void end(); //!< end
  163. protected:
  164. void select(); //!< select
  165. void unselect(); //!< unselect
  166. uint8_t _slaveSelectPin; //!< Slave select pin
  167. uint16_t _jedecID; //!< JEDEC ID
  168. uint8_t _SPCR; //!< SPCR
  169. uint8_t _SPSR; //!< SPSR
  170. #ifdef SPI_HAS_TRANSACTION
  171. SPISettings _settings;
  172. #endif
  173. };
  174. #endif