My Marlin configs for Fabrikator Mini and CTC i3 Pro B
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.

SPIFlashStorage.h 3.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. /**
  2. * Marlin 3D Printer Firmware
  3. * Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
  4. *
  5. * Based on Sprinter and grbl.
  6. * Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
  7. *
  8. * This program is free software: you can redistribute it and/or modify
  9. * it under the terms of the GNU General Public License as published by
  10. * the Free Software Foundation, either version 3 of the License, or
  11. * (at your option) any later version.
  12. *
  13. * This program is distributed in the hope that it will be useful,
  14. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. * GNU General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  20. *
  21. */
  22. #pragma once
  23. #include "../../../../libs/W25Qxx.h"
  24. #define HAS_SPI_FLASH_COMPRESSION 1
  25. /**
  26. * This class manages and optimizes SPI Flash data storage,
  27. * keeping an internal buffer to write and save full SPI flash
  28. * pages as needed.
  29. *
  30. * Since the data is always in the buffer, the class is also
  31. * able to support fast on-the-fly RLE compression/decompression.
  32. *
  33. * In testing with the current LVGL_UI it compacts 2.9MB of icons
  34. * (which have lots of runs) down to 370kB!!! As a result the UI
  35. * refresh rate becomes faster and now all LVGL UI can fit into a
  36. * tiny 2MB SPI Flash, such as the Chitu Board.
  37. *
  38. * == Usage ==
  39. *
  40. * Writing:
  41. *
  42. * The class keeps an internal buffer that caches data until it
  43. * fits into a full SPI Flash page. Each time the buffer fills up
  44. * the page is saved to SPI Flash. Sequential writes are optimal.
  45. *
  46. * SPIFlashStorage.beginWrite(myStartAddress);
  47. * while (there is data to write)
  48. * SPIFlashStorage.addData(myBuffer, bufferSize);
  49. * SPIFlashStorage.endWrite(); // Flush remaining buffer data
  50. *
  51. * Reading:
  52. *
  53. * When reading, it loads a full page from SPI Flash at once and
  54. * keeps it in a private SRAM buffer. Data is loaded as needed to
  55. * fullfill requests. Sequential reads are optimal.
  56. *
  57. * SPIFlashStorage.beginRead(myStartAddress);
  58. * while (there is data to read)
  59. * SPIFlashStorage.readData(myBuffer, bufferSize);
  60. *
  61. * Compression:
  62. *
  63. * The biggest advantage of this class is the RLE compression.
  64. * With compression activated a second buffer holds the compressed
  65. * data, so when writing data, as this buffer becomes full it is
  66. * flushed to SPI Flash.
  67. *
  68. * The same goes for reading: A compressed page is read from SPI
  69. * flash, and the data is uncompressed as needed to provide the
  70. * requested amount of data.
  71. */
  72. class SPIFlashStorage {
  73. public:
  74. // Write operation
  75. static void beginWrite(uint32_t startAddress);
  76. static void endWrite();
  77. static void writeData(uint8_t* data, uint16_t size);
  78. // Read operation
  79. static void beginRead(uint32_t startAddress);
  80. static void readData(uint8_t* data, uint16_t size);
  81. static uint32_t getCurrentPage() { return m_currentPage; }
  82. private:
  83. static void flushPage();
  84. static void savePage(uint8_t* buffer);
  85. static void loadPage(uint8_t* buffer);
  86. static void readPage();
  87. static uint16_t inData(uint8_t* data, uint16_t size);
  88. static uint16_t outData(uint8_t* data, uint16_t size);
  89. static uint8_t m_pageData[SPI_FLASH_PageSize];
  90. static uint32_t m_currentPage;
  91. static uint16_t m_pageDataUsed;
  92. static inline uint16_t pageDataFree() { return SPI_FLASH_PageSize - m_pageDataUsed; }
  93. static uint32_t m_startAddress;
  94. #if HAS_SPI_FLASH_COMPRESSION
  95. static uint8_t m_compressedData[SPI_FLASH_PageSize];
  96. static uint16_t m_compressedDataUsed;
  97. static inline uint16_t compressedDataFree() { return SPI_FLASH_PageSize - m_compressedDataUsed; }
  98. #endif
  99. };
  100. extern SPIFlashStorage SPIFlash;