W25QXX SPI Flash support (#18897)

Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
This commit is contained in:
Victor Oliveira 2020-08-08 21:24:31 -03:00 committed by GitHub
parent 58cfdb8f57
commit 0a1b865987
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 140 additions and 84 deletions

View file

@ -0,0 +1,92 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2020 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#include "../../inc/MarlinConfig.h"
#if ALL(HAS_SPI_FLASH, SDSUPPORT, MARLIN_DEV_MODE)
#include "../gcode.h"
#include "../../sd/cardreader.h"
#include "../../libs/W25Qxx.h"
/**
* M993: Backup SPI Flash to SD
*/
void GcodeSuite::M993() {
if (!card.isMounted()) card.mount();
char fname[] = "spiflash.bin";
card.openFileWrite(fname);
if (!card.isFileOpen()) {
SERIAL_ECHOLNPAIR("Failed to open ", fname, " to write.");
return;
}
W25QXXFlash W25QXX;
uint8_t buf[1024];
uint32_t addr = 0;
W25QXX.init(SPI_QUARTER_SPEED);
SERIAL_ECHOPGM("Save SPI Flash");
while (addr < SPI_FLASH_SIZE) {
W25QXX.SPI_FLASH_BufferRead(buf, addr, COUNT(buf));
addr += COUNT(buf);
card.write(buf, COUNT(buf));
if (addr % (COUNT(buf) * 10) == 0) SERIAL_CHAR('.');
}
SERIAL_ECHOLNPGM(" done");
card.closefile();
}
/**
* M994: Load a backup from SD to SPI Flash
*/
void GcodeSuite::M994() {
if (!card.isMounted()) card.mount();
char fname[] = "spiflash.bin";
card.openFileRead(fname);
if (!card.isFileOpen()) {
SERIAL_ECHOLNPAIR("Failed to open ", fname, " to read.");
return;
}
W25QXXFlash W25QXX;
uint8_t buf[1024];
uint32_t addr = 0;
W25QXX.init(SPI_QUARTER_SPEED);
W25QXX.SPI_FLASH_BulkErase();
SERIAL_ECHOPGM("Load SPI Flash");
while(addr < SPI_FLASH_SIZE) {
card.read(buf, COUNT(buf));
W25QXX.SPI_FLASH_BufferWrite(buf, addr, COUNT(buf));
addr += COUNT(buf);
if (addr % (COUNT(buf) * 10) == 0) SERIAL_CHAR('.');
}
SERIAL_ECHOLNPGM(" done");
card.closefile();
}
#endif // HAS_SPI_FLASH && SDSUPPORT && MARLIN_DEV_MODE

View file

@ -871,6 +871,11 @@ void GcodeSuite::process_parsed_command(const bool no_ok/*=false*/) {
case 422: M422(); break; // M422: Set Z Stepper automatic alignment position using probe
#endif
#if BOTH(HAS_SPI_FLASH, SDSUPPORT)
case 993: M993(); break; // M993: Backup SPI Flash to SD
case 994: M994(); break; // M994: Load a Backup from SD to SPI Flash
#endif
#if ENABLED(TOUCH_SCREEN_CALIBRATION)
case 995: M995(); break; // M995: Touch screen calibration for TFT display
#endif

View file

@ -276,6 +276,8 @@
* ************ Custom codes - This can change to suit future G-code regulations
* G425 - Calibrate using a conductive object. (Requires CALIBRATION_GCODE)
* M928 - Start SD logging: "M928 filename.gco". Stop with M29. (Requires SDSUPPORT)
* M993 - Backup SPI Flash to SD
* M994 - Load a Backup from SD to SPI Flash
* M995 - Touch screen calibration for TFT display
* M997 - Perform in-application firmware update
* M999 - Restart after being stopped by error
@ -846,6 +848,11 @@ private:
TERN_(TOUCH_SCREEN_CALIBRATION, static void M995());
#if BOTH(HAS_SPI_FLASH, SDSUPPORT)
static void M993();
static void M994();
#endif
TERN_(PLATFORM_M997_SUPPORT, static void M997());
static void M999();

View file

@ -27,6 +27,8 @@
#include "../../../../inc/MarlinConfig.h"
#include "SPIFlashStorage.h"
extern W25QXXFlash W25QXX;
uint8_t SPIFlashStorage::m_pageData[SPI_FLASH_PageSize];
uint32_t SPIFlashStorage::m_currentPage;
uint16_t SPIFlashStorage::m_pageDataUsed;

View file

@ -21,7 +21,7 @@
*/
#pragma once
#include "W25Qxx.h"
#include "../../../../libs/W25Qxx.h"
#define HAS_SPI_FLASH_COMPRESSION 1

View file

@ -27,7 +27,6 @@
#include "SPI_TFT.h"
#endif
#include "W25Qxx.h"
#include "tft_lvgl_configuration.h"
#include "pic_manager.h"
@ -50,6 +49,7 @@
#include "../../../../feature/pause.h"
#endif
W25QXXFlash W25QXX;
CFG_ITMES gCfgItems;
UI_CFG uiCfg;
DISP_STATE_STACK disp_state_stack;

View file

@ -29,7 +29,6 @@
#include "tft_lvgl_configuration.h"
#include "draw_ready_print.h"
#include "W25Qxx.h"
#include "mks_hardware_test.h"
#include "draw_ui.h"
#include "pic_manager.h"

View file

@ -29,10 +29,10 @@
#include "mks_hardware_test.h"
#include "SPIFlashStorage.h"
#include "W25Qxx.h"
#include "../../../../libs/W25Qxx.h"
#include "../../../../MarlinCore.h"
#include "../../../../sd/cardreader.h"
#include "../../../../MarlinCore.h"
extern uint16_t DeviceCode;
extern unsigned char bmp_public_buf[17 * 1024];

View file

@ -23,6 +23,8 @@
#include "../../../../inc/MarlinConfig.h"
#include "../../../../libs/W25Qxx.h"
#include <lvgl.h>
#include <stdint.h>
@ -154,6 +156,8 @@ extern void spi_flash_read_test();
extern void default_view_Read(uint8_t *default_view_Rbuff, uint32_t default_view_Readsize);
extern void flash_view_Read(uint8_t *flash_view_Rbuff, uint32_t flash_view_Readsize);
extern W25QXXFlash W25QXX;
#ifdef __cplusplus
} /* C-declarations for C++ */
#endif

View file

@ -35,7 +35,6 @@
#include "tft_lvgl_configuration.h"
#include "draw_ready_print.h"
#include "W25Qxx.h"
#include "pic_manager.h"
#include "mks_hardware_test.h"
#include "draw_ui.h"

View file

@ -19,13 +19,12 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#include "../../../../inc/MarlinConfigPre.h"
#if 1 // ENABLED(SPI_FLASH)
#if HAS_TFT_LVGL_UI
#include "../inc/MarlinConfig.h"
#if HAS_SPI_FLASH
#include <SPI.h>
#include "../../../../inc/MarlinConfig.h"
#include "W25Qxx.h"
@ -45,9 +44,7 @@
#define W25QXX_CS_H OUT_WRITE(SPI_FLASH_CS_PIN, HIGH)
#define W25QXX_CS_L OUT_WRITE(SPI_FLASH_CS_PIN, LOW)
ext_FLASH W25QXX;
void ext_FLASH::init(uint8_t spiRate) {
void W25QXXFlash::init(uint8_t spiRate) {
OUT_WRITE(SPI_FLASH_CS_PIN, HIGH);
@ -85,12 +82,12 @@ void ext_FLASH::init(uint8_t spiRate) {
*
* @details
*/
uint8_t ext_FLASH::spi_flash_Rec() {
uint8_t W25QXXFlash::spi_flash_Rec() {
uint8_t returnByte = SPI.transfer(ff);
return returnByte;
}
uint8_t ext_FLASH::spi_flash_read_write_byte(uint8_t data) {
uint8_t W25QXXFlash::spi_flash_read_write_byte(uint8_t data) {
uint8_t returnByte = SPI.transfer(data);
return returnByte;
}
@ -104,7 +101,7 @@ uint8_t ext_FLASH::spi_flash_read_write_byte(uint8_t data) {
*
* @details Uses DMA
*/
void ext_FLASH::spi_flash_Read(uint8_t* buf, uint16_t nbyte) { SPI.dmaTransfer(0, const_cast<uint8_t*>(buf), nbyte); }
void W25QXXFlash::spi_flash_Read(uint8_t* buf, uint16_t nbyte) { SPI.dmaTransfer(0, const_cast<uint8_t*>(buf), nbyte); }
/**
* @brief Send a single byte on SPI port
@ -113,7 +110,7 @@ void ext_FLASH::spi_flash_Read(uint8_t* buf, uint16_t nbyte) { SPI.dmaTransfer(0
*
* @details
*/
void ext_FLASH::spi_flash_Send(uint8_t b) { SPI.send(b); }
void W25QXXFlash::spi_flash_Send(uint8_t b) { SPI.send(b); }
/**
* @brief Write token and then write from 512 byte buffer to SPI (for SD card)
@ -123,12 +120,12 @@ void ext_FLASH::spi_flash_Send(uint8_t b) { SPI.send(b); }
*
* @details Use DMA
*/
void ext_FLASH::spi_flash_SendBlock(uint8_t token, const uint8_t* buf) {
void W25QXXFlash::spi_flash_SendBlock(uint8_t token, const uint8_t* buf) {
SPI.send(token);
SPI.dmaSend(const_cast<uint8_t*>(buf), 512);
}
uint16_t ext_FLASH::W25QXX_ReadID(void) {
uint16_t W25QXXFlash::W25QXX_ReadID(void) {
uint16_t Temp = 0;
W25QXX_CS_L;
spi_flash_Send(0x90);
@ -141,7 +138,7 @@ uint16_t ext_FLASH::W25QXX_ReadID(void) {
return Temp;
}
void ext_FLASH::SPI_FLASH_WriteEnable(void) {
void W25QXXFlash::SPI_FLASH_WriteEnable(void) {
/* Select the FLASH: Chip Select low */
W25QXX_CS_L;
/* Send "Write Enable" instruction */
@ -159,7 +156,7 @@ void ext_FLASH::SPI_FLASH_WriteEnable(void) {
* Output : None
* Return : None
*******************************************************************************/
void ext_FLASH::SPI_FLASH_WaitForWriteEnd(void) {
void W25QXXFlash::SPI_FLASH_WaitForWriteEnd(void) {
uint8_t FLASH_Status = 0;
/* Select the FLASH: Chip Select low */
@ -178,7 +175,7 @@ void ext_FLASH::SPI_FLASH_WaitForWriteEnd(void) {
W25QXX_CS_H;
}
void ext_FLASH::SPI_FLASH_SectorErase(uint32_t SectorAddr) {
void W25QXXFlash::SPI_FLASH_SectorErase(uint32_t SectorAddr) {
/* Send write enable instruction */
SPI_FLASH_WriteEnable();
@ -200,7 +197,7 @@ void ext_FLASH::SPI_FLASH_SectorErase(uint32_t SectorAddr) {
SPI_FLASH_WaitForWriteEnd();
}
void ext_FLASH::SPI_FLASH_BlockErase(uint32_t BlockAddr) {
void W25QXXFlash::SPI_FLASH_BlockErase(uint32_t BlockAddr) {
SPI_FLASH_WriteEnable();
W25QXX_CS_L;
/* Send Sector Erase instruction */
@ -224,7 +221,7 @@ void ext_FLASH::SPI_FLASH_BlockErase(uint32_t BlockAddr) {
* Output : None
* Return : None
*******************************************************************************/
void ext_FLASH::SPI_FLASH_BulkErase(void) {
void W25QXXFlash::SPI_FLASH_BulkErase(void) {
/* Send write enable instruction */
SPI_FLASH_WriteEnable();
@ -253,7 +250,7 @@ void ext_FLASH::SPI_FLASH_BulkErase(void) {
* Output : None
* Return : None
*******************************************************************************/
void ext_FLASH::SPI_FLASH_PageWrite(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite) {
void W25QXXFlash::SPI_FLASH_PageWrite(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite) {
/* Enable the write access to the FLASH */
SPI_FLASH_WriteEnable();
@ -296,7 +293,7 @@ void ext_FLASH::SPI_FLASH_PageWrite(uint8_t* pBuffer, uint32_t WriteAddr, uint16
* Output : None
* Return : None
*******************************************************************************/
void ext_FLASH::SPI_FLASH_BufferWrite(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite) {
void W25QXXFlash::SPI_FLASH_BufferWrite(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite) {
uint8_t NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0, temp = 0;
Addr = WriteAddr % SPI_FLASH_PageSize;
@ -361,7 +358,7 @@ void ext_FLASH::SPI_FLASH_BufferWrite(uint8_t* pBuffer, uint32_t WriteAddr, uint
* Output : None
* Return : None
*******************************************************************************/
void ext_FLASH::SPI_FLASH_BufferRead(uint8_t* pBuffer, uint32_t ReadAddr, uint16_t NumByteToRead) {
void W25QXXFlash::SPI_FLASH_BufferRead(uint8_t* pBuffer, uint32_t ReadAddr, uint16_t NumByteToRead) {
/* Select the FLASH: Chip Select low */
W25QXX_CS_L;
@ -389,7 +386,4 @@ void ext_FLASH::SPI_FLASH_BufferRead(uint8_t* pBuffer, uint32_t ReadAddr, uint16
W25QXX_CS_H;
}
void ext_FLASH::lv_pic_read(uint8_t *P_Rbuff, uint32_t addr, uint32_t size) {SPI_FLASH_BufferRead((uint8_t *)P_Rbuff, addr, size);}
#endif // HAS_TFT_LVGL_UI
#endif // 1 ... SPI_FLASH
#endif // HAS_SPI_FLASH

View file

@ -52,49 +52,7 @@
#define SPI_FLASH_PageSize 256
#define SPI_FLASH_PerWritePageSize 256
#if 0
#define PIC_NAME_MAX_LEN 50
#define LOGO_MAX_SIZE (300*1024)
#define TITLELOGO_MAX_SIZE (150*1024)
#define DEFAULT_VIEW_MAX_SIZE (200*200*2)
#define FLASH_VIEW_MAX_SIZE (200*200*2)
//Robin 2
#define PIC_NAME_ADDR 0x003000
#define PIC_SIZE_ADDR 0x007000
#define PIC_COUNTER_ADDR 0x008000
#define PIC_LOGO_ADDR 0x009000
//#define PIC_DATA_ADDR 0x02f000
#define DEFAULT_VIEW_ADDR 0XC5800
#define BAK_VIEW_ADDR (DEFAULT_VIEW_ADDR+90*1024)
#define PIC_ICON_LOGO_ADDR (BAK_VIEW_ADDR+80*1024)
#define PIC_DATA_ADDR (PIC_ICON_LOGO_ADDR+350*1024)
#define FONTINFOADDR 0x600000
#define UNIGBK_FLASH_ADDR (FONTINFOADDR+4096) // 4*1024
#define GBK_FLASH_ADDR (UNIGBK_FLASH_ADDR+180224) // 176*1024
#define PER_PIC_MAX_SPACE (32*1024)
union union32 {
uint8_t bytes[4];
uint32_t dwords;
};
struct pic_msg {
uint8_t name[PIC_NAME_MAX_LEN];
union union32 size;
};
typedef struct pic_msg PIC_MSG;
#endif // if 0
class ext_FLASH {
class W25QXXFlash {
public:
void init(uint8_t spiRate);
static uint8_t spi_flash_Rec();
@ -111,14 +69,8 @@ public:
static void SPI_FLASH_PageWrite(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite);
static void SPI_FLASH_BufferWrite(uint8_t* pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite);
static void SPI_FLASH_BufferRead(uint8_t* pBuffer, uint32_t ReadAddr, uint16_t NumByteToRead);
//uint32_t lv_get_pic_addr(uint8_t *Pname);
void lv_pic_read(uint8_t *P_Rbuff, uint32_t addr, uint32_t size);
};
extern ext_FLASH W25QXX;
//extern uint32_t lv_get_pic_addr(uint8_t *Pname);
//#ifdef __cplusplus
//} /* C-declarations for C++ */
//#endif

View file

@ -240,8 +240,9 @@
#define ILI9488_ORIENTATION ILI9488_MADCTL_MX | ILI9488_MADCTL_MV
#endif
#define SPI_FLASH
#if ENABLED(SPI_FLASH)
#define HAS_SPI_FLASH 1
#define SPI_FLASH_SIZE 0x1000000 // 16MB
#if HAS_SPI_FLASH
#define W25QXX_CS_PIN PB12
#define W25QXX_MOSI_PIN PB15
#define W25QXX_MISO_PIN PB14

View file

@ -398,8 +398,9 @@
#endif // HAS_SPI_LCD
#define SPI_FLASH
#if ENABLED(SPI_FLASH)
#define HAS_SPI_FLASH 1
#define SPI_FLASH_SIZE 0x1000000 // 16MB
#if HAS_SPI_FLASH
#define W25QXX_CS_PIN PB12
#define W25QXX_MOSI_PIN PB15
#define W25QXX_MISO_PIN PB14