Multi-Volume. Select Media for LVGL (#21344)

This commit is contained in:
Victor Oliveira
2021-04-13 19:34:19 -03:00
committed by GitHub
parent a5f0075a60
commit 138340ee99
29 changed files with 546 additions and 279 deletions

View File

@ -30,7 +30,7 @@
#include "../inc/MarlinConfig.h"
#if ENABLED(SDSUPPORT) && NONE(USB_FLASH_DRIVE_SUPPORT, SDIO_SUPPORT)
#if NEED_SD2CARD_SPI
/* Enable FAST CRC computations - You can trade speed for FLASH space if
* needed by disabling the following define */
@ -88,7 +88,7 @@
#endif
// Send command and return error code. Return zero for OK
uint8_t Sd2Card::cardCommand(const uint8_t cmd, const uint32_t arg) {
uint8_t DiskIODriver_SPI_SD::cardCommand(const uint8_t cmd, const uint32_t arg) {
// Select card
chipSelect();
@ -133,7 +133,7 @@ uint8_t Sd2Card::cardCommand(const uint8_t cmd, const uint32_t arg) {
* \return The number of 512 byte data blocks in the card
* or zero if an error occurs.
*/
uint32_t Sd2Card::cardSize() {
uint32_t DiskIODriver_SPI_SD::cardSize() {
csd_t csd;
if (!readCSD(&csd)) return 0;
if (csd.v1.csd_ver == 0) {
@ -155,12 +155,12 @@ uint32_t Sd2Card::cardSize() {
}
}
void Sd2Card::chipDeselect() {
void DiskIODriver_SPI_SD::chipDeselect() {
extDigitalWrite(chipSelectPin_, HIGH);
spiSend(0xFF); // Ensure MISO goes high impedance
}
void Sd2Card::chipSelect() {
void DiskIODriver_SPI_SD::chipSelect() {
spiInit(spiRate_);
extDigitalWrite(chipSelectPin_, LOW);
}
@ -178,7 +178,7 @@ void Sd2Card::chipSelect() {
*
* \return true for success, false for failure.
*/
bool Sd2Card::erase(uint32_t firstBlock, uint32_t lastBlock) {
bool DiskIODriver_SPI_SD::erase(uint32_t firstBlock, uint32_t lastBlock) {
if (ENABLED(SDCARD_READONLY)) return false;
csd_t csd;
@ -216,7 +216,7 @@ bool Sd2Card::erase(uint32_t firstBlock, uint32_t lastBlock) {
* \return true if single block erase is supported.
* false if single block erase is not supported.
*/
bool Sd2Card::eraseSingleBlockEnable() {
bool DiskIODriver_SPI_SD::eraseSingleBlockEnable() {
csd_t csd;
return readCSD(&csd) ? csd.v1.erase_blk_en : false;
}
@ -230,7 +230,7 @@ bool Sd2Card::eraseSingleBlockEnable() {
* \return true for success, false for failure.
* The reason for failure can be determined by calling errorCode() and errorData().
*/
bool Sd2Card::init(const uint8_t sckRateID, const pin_t chipSelectPin) {
bool DiskIODriver_SPI_SD::init(const uint8_t sckRateID, const pin_t chipSelectPin) {
#if IS_TEENSY_35_36 || IS_TEENSY_40_41
chipSelectPin_ = BUILTIN_SDCARD;
const uint8_t ret = SDHC_CardInit();
@ -324,10 +324,12 @@ bool Sd2Card::init(const uint8_t sckRateID, const pin_t chipSelectPin) {
}
chipDeselect();
ready = true;
return setSckRate(sckRateID);
FAIL:
chipDeselect();
ready = false;
return false;
}
@ -338,7 +340,7 @@ bool Sd2Card::init(const uint8_t sckRateID, const pin_t chipSelectPin) {
* \param[out] dst Pointer to the location that will receive the data.
* \return true for success, false for failure.
*/
bool Sd2Card::readBlock(uint32_t blockNumber, uint8_t *dst) {
bool DiskIODriver_SPI_SD::readBlock(uint32_t blockNumber, uint8_t *dst) {
#if IS_TEENSY_35_36 || IS_TEENSY_40_41
return 0 == SDHC_CardReadBlock(dst, blockNumber);
#endif
@ -378,7 +380,7 @@ bool Sd2Card::readBlock(uint32_t blockNumber, uint8_t *dst) {
*
* \return true for success, false for failure.
*/
bool Sd2Card::readData(uint8_t *dst) {
bool DiskIODriver_SPI_SD::readData(uint8_t *dst) {
chipSelect();
return readData(dst, 512);
}
@ -445,7 +447,7 @@ bool Sd2Card::readData(uint8_t *dst) {
#endif
#endif // SD_CHECK_AND_RETRY
bool Sd2Card::readData(uint8_t *dst, const uint16_t count) {
bool DiskIODriver_SPI_SD::readData(uint8_t *dst, const uint16_t count) {
bool success = false;
const millis_t read_timeout = millis() + SD_READ_TIMEOUT;
@ -477,7 +479,7 @@ bool Sd2Card::readData(uint8_t *dst, const uint16_t count) {
}
/** read CID or CSR register */
bool Sd2Card::readRegister(const uint8_t cmd, void *buf) {
bool DiskIODriver_SPI_SD::readRegister(const uint8_t cmd, void *buf) {
uint8_t *dst = reinterpret_cast<uint8_t*>(buf);
if (cardCommand(cmd, 0)) {
error(SD_CARD_ERROR_READ_REG);
@ -497,7 +499,7 @@ bool Sd2Card::readRegister(const uint8_t cmd, void *buf) {
*
* \return true for success, false for failure.
*/
bool Sd2Card::readStart(uint32_t blockNumber) {
bool DiskIODriver_SPI_SD::readStart(uint32_t blockNumber) {
if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9;
const bool success = !cardCommand(CMD18, blockNumber);
@ -511,7 +513,7 @@ bool Sd2Card::readStart(uint32_t blockNumber) {
*
* \return true for success, false for failure.
*/
bool Sd2Card::readStop() {
bool DiskIODriver_SPI_SD::readStop() {
chipSelect();
const bool success = !cardCommand(CMD12, 0);
if (!success) error(SD_CARD_ERROR_CMD12);
@ -531,7 +533,7 @@ bool Sd2Card::readStop() {
* \return The value one, true, is returned for success and the value zero,
* false, is returned for an invalid value of \a sckRateID.
*/
bool Sd2Card::setSckRate(const uint8_t sckRateID) {
bool DiskIODriver_SPI_SD::setSckRate(const uint8_t sckRateID) {
const bool success = (sckRateID <= 6);
if (success) spiRate_ = sckRateID; else error(SD_CARD_ERROR_SCK_RATE);
return success;
@ -542,12 +544,14 @@ bool Sd2Card::setSckRate(const uint8_t sckRateID) {
* \param[in] timeout_ms Timeout to abort.
* \return true for success, false for timeout.
*/
bool Sd2Card::waitNotBusy(const millis_t timeout_ms) {
bool DiskIODriver_SPI_SD::waitNotBusy(const millis_t timeout_ms) {
const millis_t wait_timeout = millis() + timeout_ms;
while (spiRec() != 0xFF) if (ELAPSED(millis(), wait_timeout)) return false;
return true;
}
void DiskIODriver_SPI_SD::error(const uint8_t code) { errorCode_ = code; }
/**
* Write a 512 byte block to an SD card.
*
@ -555,7 +559,7 @@ bool Sd2Card::waitNotBusy(const millis_t timeout_ms) {
* \param[in] src Pointer to the location of the data to be written.
* \return true for success, false for failure.
*/
bool Sd2Card::writeBlock(uint32_t blockNumber, const uint8_t *src) {
bool DiskIODriver_SPI_SD::writeBlock(uint32_t blockNumber, const uint8_t *src) {
if (ENABLED(SDCARD_READONLY)) return false;
#if IS_TEENSY_35_36 || IS_TEENSY_40_41
@ -586,7 +590,7 @@ bool Sd2Card::writeBlock(uint32_t blockNumber, const uint8_t *src) {
* \param[in] src Pointer to the location of the data to be written.
* \return true for success, false for failure.
*/
bool Sd2Card::writeData(const uint8_t *src) {
bool DiskIODriver_SPI_SD::writeData(const uint8_t *src) {
if (ENABLED(SDCARD_READONLY)) return false;
bool success = true;
@ -601,7 +605,7 @@ bool Sd2Card::writeData(const uint8_t *src) {
}
// Send one block of data for write block or write multiple blocks
bool Sd2Card::writeData(const uint8_t token, const uint8_t *src) {
bool DiskIODriver_SPI_SD::writeData(const uint8_t token, const uint8_t *src) {
if (ENABLED(SDCARD_READONLY)) return false;
const uint16_t crc = TERN(SD_CHECK_AND_RETRY, CRC_CCITT(src, 512), 0xFFFF);
@ -629,7 +633,7 @@ bool Sd2Card::writeData(const uint8_t token, const uint8_t *src) {
*
* \return true for success, false for failure.
*/
bool Sd2Card::writeStart(uint32_t blockNumber, const uint32_t eraseCount) {
bool DiskIODriver_SPI_SD::writeStart(uint32_t blockNumber, const uint32_t eraseCount) {
if (ENABLED(SDCARD_READONLY)) return false;
bool success = false;
@ -650,7 +654,7 @@ bool Sd2Card::writeStart(uint32_t blockNumber, const uint32_t eraseCount) {
*
* \return true for success, false for failure.
*/
bool Sd2Card::writeStop() {
bool DiskIODriver_SPI_SD::writeStop() {
if (ENABLED(SDCARD_READONLY)) return false;
bool success = false;
@ -666,4 +670,4 @@ bool Sd2Card::writeStop() {
return success;
}
#endif // SDSUPPORT
#endif // NEED_SD2CARD_SPI

View File

@ -35,47 +35,50 @@
#include "SdFatConfig.h"
#include "SdInfo.h"
#include "disk_io_driver.h"
#include <stdint.h>
uint16_t const SD_INIT_TIMEOUT = 2000, // init timeout ms
SD_ERASE_TIMEOUT = 10000, // erase timeout ms
SD_READ_TIMEOUT = 300, // read timeout ms
SD_WRITE_TIMEOUT = 600; // write time out ms
uint16_t const SD_INIT_TIMEOUT = 2000, // (ms) Init timeout
SD_ERASE_TIMEOUT = 10000, // (ms) Erase timeout
SD_READ_TIMEOUT = 300, // (ms) Read timeout
SD_WRITE_TIMEOUT = 600; // (ms) Write timeout
// SD card errors
uint8_t const SD_CARD_ERROR_CMD0 = 0x01, // timeout error for command CMD0 (initialize card in SPI mode)
SD_CARD_ERROR_CMD8 = 0x02, // CMD8 was not accepted - not a valid SD card
SD_CARD_ERROR_CMD12 = 0x03, // card returned an error response for CMD12 (write stop)
SD_CARD_ERROR_CMD17 = 0x04, // card returned an error response for CMD17 (read block)
SD_CARD_ERROR_CMD18 = 0x05, // card returned an error response for CMD18 (read multiple block)
SD_CARD_ERROR_CMD24 = 0x06, // card returned an error response for CMD24 (write block)
SD_CARD_ERROR_CMD25 = 0x07, // WRITE_MULTIPLE_BLOCKS command failed
SD_CARD_ERROR_CMD58 = 0x08, // card returned an error response for CMD58 (read OCR)
SD_CARD_ERROR_ACMD23 = 0x09, // SET_WR_BLK_ERASE_COUNT failed
SD_CARD_ERROR_ACMD41 = 0x0A, // ACMD41 initialization process timeout
SD_CARD_ERROR_BAD_CSD = 0x0B, // card returned a bad CSR version field
SD_CARD_ERROR_ERASE = 0x0C, // erase block group command failed
SD_CARD_ERROR_ERASE_SINGLE_BLOCK = 0x0D, // card not capable of single block erase
SD_CARD_ERROR_ERASE_TIMEOUT = 0x0E, // Erase sequence timed out
SD_CARD_ERROR_READ = 0x0F, // card returned an error token instead of read data
SD_CARD_ERROR_READ_REG = 0x10, // read CID or CSD failed
SD_CARD_ERROR_READ_TIMEOUT = 0x11, // timeout while waiting for start of read data
SD_CARD_ERROR_STOP_TRAN = 0x12, // card did not accept STOP_TRAN_TOKEN
SD_CARD_ERROR_WRITE = 0x13, // card returned an error token as a response to a write operation
SD_CARD_ERROR_WRITE_BLOCK_ZERO = 0x14, // REMOVE - not used ... attempt to write protected block zero
SD_CARD_ERROR_WRITE_MULTIPLE = 0x15, // card did not go ready for a multiple block write
SD_CARD_ERROR_WRITE_PROGRAMMING = 0x16, // card returned an error to a CMD13 status check after a write
SD_CARD_ERROR_WRITE_TIMEOUT = 0x17, // timeout occurred during write programming
SD_CARD_ERROR_SCK_RATE = 0x18, // incorrect rate selected
SD_CARD_ERROR_INIT_NOT_CALLED = 0x19, // init() not called
// 0x1A is unused now, it was: card returned an error for CMD59 (CRC_ON_OFF)
SD_CARD_ERROR_READ_CRC = 0x1B; // invalid read CRC
typedef enum : uint8_t {
SD_CARD_ERROR_CMD0 = 0x01, // Timeout error for command CMD0 (initialize card in SPI mode)
SD_CARD_ERROR_CMD8 = 0x02, // CMD8 was not accepted - not a valid SD card
SD_CARD_ERROR_CMD12 = 0x03, // Card returned an error response for CMD12 (write stop)
SD_CARD_ERROR_CMD17 = 0x04, // Card returned an error response for CMD17 (read block)
SD_CARD_ERROR_CMD18 = 0x05, // Card returned an error response for CMD18 (read multiple block)
SD_CARD_ERROR_CMD24 = 0x06, // Card returned an error response for CMD24 (write block)
SD_CARD_ERROR_CMD25 = 0x07, // WRITE_MULTIPLE_BLOCKS command failed
SD_CARD_ERROR_CMD58 = 0x08, // Card returned an error response for CMD58 (read OCR)
SD_CARD_ERROR_ACMD23 = 0x09, // SET_WR_BLK_ERASE_COUNT failed
SD_CARD_ERROR_ACMD41 = 0x0A, // ACMD41 initialization process timeout
SD_CARD_ERROR_BAD_CSD = 0x0B, // Card returned a bad CSR version field
SD_CARD_ERROR_ERASE = 0x0C, // Erase block group command failed
SD_CARD_ERROR_ERASE_SINGLE_BLOCK = 0x0D, // Card not capable of single block erase
SD_CARD_ERROR_ERASE_TIMEOUT = 0x0E, // Erase sequence timed out
SD_CARD_ERROR_READ = 0x0F, // Card returned an error token instead of read data
SD_CARD_ERROR_READ_REG = 0x10, // Read CID or CSD failed
SD_CARD_ERROR_READ_TIMEOUT = 0x11, // Timeout while waiting for start of read data
SD_CARD_ERROR_STOP_TRAN = 0x12, // Card did not accept STOP_TRAN_TOKEN
SD_CARD_ERROR_WRITE = 0x13, // Card returned an error token as a response to a write operation
SD_CARD_ERROR_WRITE_BLOCK_ZERO = 0x14, // REMOVE - not used ... attempt to write protected block zero
SD_CARD_ERROR_WRITE_MULTIPLE = 0x15, // Card did not go ready for a multiple block write
SD_CARD_ERROR_WRITE_PROGRAMMING = 0x16, // Card returned an error to a CMD13 status check after a write
SD_CARD_ERROR_WRITE_TIMEOUT = 0x17, // Timeout occurred during write programming
SD_CARD_ERROR_SCK_RATE = 0x18, // Incorrect rate selected
SD_CARD_ERROR_INIT_NOT_CALLED = 0x19, // Init() not called
// 0x1A is unused now, it was: card returned an error for CMD59 (CRC_ON_OFF)
SD_CARD_ERROR_READ_CRC = 0x1B // Invalid read CRC
} sd_error_code_t;
// card types
uint8_t const SD_CARD_TYPE_SD1 = 1, // Standard capacity V1 SD card
SD_CARD_TYPE_SD2 = 2, // Standard capacity V2 SD card
SD_CARD_TYPE_SDHC = 3; // High Capacity SD card
uint8_t const SD_CARD_TYPE_SD1 = 1, // Standard capacity V1 SD card
SD_CARD_TYPE_SD2 = 2, // Standard capacity V2 SD card
SD_CARD_TYPE_SDHC = 3; // High Capacity SD card
/**
* Define SOFTWARE_SPI to use bit-bang SPI
@ -93,12 +96,11 @@ uint8_t const SD_CARD_TYPE_SD1 = 1, // Standard capacity V1
* \class Sd2Card
* \brief Raw access to SD and SDHC flash memory cards.
*/
class Sd2Card {
class DiskIODriver_SPI_SD : public DiskIODriver {
public:
Sd2Card() : errorCode_(SD_CARD_ERROR_INIT_NOT_CALLED), type_(0) {}
DiskIODriver_SPI_SD() : errorCode_(SD_CARD_ERROR_INIT_NOT_CALLED), type_(0) {}
uint32_t cardSize();
bool erase(uint32_t firstBlock, uint32_t lastBlock);
bool eraseSingleBlockEnable();
@ -106,7 +108,7 @@ public:
* Set SD error code.
* \param[in] code value for error code.
*/
inline void error(const uint8_t code) { errorCode_ = code; }
void error(const uint8_t code);
/**
* \return error code for last error. See Sd2Card.h for a list of error codes.
@ -122,9 +124,15 @@ public:
*
* \return true for success or false for failure.
*/
bool init(const uint8_t sckRateID, const pin_t chipSelectPin);
bool init(const uint8_t sckRateID, const pin_t chipSelectPin) override;
bool readBlock(uint32_t block, uint8_t *dst);
bool setSckRate(const uint8_t sckRateID);
/**
* Return the card type: SD V1, SD V2 or SDHC
* \return 0 - SD V1, 1 - SD V2, or 3 - SDHC.
*/
int type() const { return type_; }
/**
* Read a card's CID register. The CID contains card identification
@ -145,24 +153,27 @@ public:
*
* \return true for success or false for failure.
*/
inline bool readCSD(csd_t *csd) { return readRegister(CMD9, csd); }
inline bool readCSD(csd_t *csd) override { return readRegister(CMD9, csd); }
bool readData(uint8_t *dst);
bool readStart(uint32_t blockNumber);
bool readStop();
bool setSckRate(const uint8_t sckRateID);
bool readData(uint8_t *dst) override;
bool readStart(uint32_t blockNumber) override;
bool readStop() override;
/**
* Return the card type: SD V1, SD V2 or SDHC
* \return 0 - SD V1, 1 - SD V2, or 3 - SDHC.
*/
int type() const {return type_;}
bool writeBlock(uint32_t blockNumber, const uint8_t *src);
bool writeData(const uint8_t *src);
bool writeStart(uint32_t blockNumber, const uint32_t eraseCount);
bool writeStop();
bool writeData(const uint8_t *src) override;
bool writeStart(const uint32_t blockNumber, const uint32_t eraseCount) override;
bool writeStop() override;
bool readBlock(uint32_t block, uint8_t *dst) override;
bool writeBlock(uint32_t blockNumber, const uint8_t *src) override;
uint32_t cardSize() override;
bool isReady() override { return ready; };
void idle() override {}
private:
bool ready = false;
uint8_t chipSelectPin_,
errorCode_,
spiRate_,

View File

@ -23,17 +23,33 @@
#include "../inc/MarlinConfig.h"
#if ENABLED(SDIO_SUPPORT)
#include "SdInfo.h"
#include "disk_io_driver.h"
bool SDIO_Init();
bool SDIO_ReadBlock(uint32_t block, uint8_t *dst);
bool SDIO_WriteBlock(uint32_t block, const uint8_t *src);
class Sd2Card {
class DiskIODriver_SDIO : public DiskIODriver {
public:
bool init(uint8_t sckRateID = 0, uint8_t chipSelectPin = 0) { return SDIO_Init(); }
bool readBlock(uint32_t block, uint8_t *dst) { return SDIO_ReadBlock(block, dst); }
bool writeBlock(uint32_t block, const uint8_t *src) { return SDIO_WriteBlock(block, src); }
};
bool init(const uint8_t sckRateID=0, const pin_t chipSelectPin=0) override { return SDIO_Init(); }
#endif // SDIO_SUPPORT
bool readCSD(csd_t *csd) override { return false; }
bool readStart(const uint32_t block) override { return false; }
bool readData(uint8_t *dst) override { return false; }
bool readStop() override { return false; }
bool writeStart(const uint32_t block, const uint32_t) override { return false; }
bool writeData(const uint8_t *src) override { return false; }
bool writeStop() override { return false; }
bool readBlock(uint32_t block, uint8_t *dst) override { return SDIO_ReadBlock(block, dst); }
bool writeBlock(uint32_t block, const uint8_t *src) override { return SDIO_WriteBlock(block, src); }
uint32_t cardSize() override { return 0; }
bool isReady() override { return true; }
void idle() override {}
};

View File

@ -39,7 +39,7 @@
*
* Each card requires about 550 bytes of SRAM so use of a Mega is recommended.
*/
#define USE_MULTIPLE_CARDS 0
#define USE_MULTIPLE_CARDS 0 //TODO? ENABLED(MULTI_VOLUME)
/**
* Call flush for endl if ENDL_CALLS_FLUSH is nonzero

View File

@ -41,10 +41,10 @@
// raw block cache
uint32_t SdVolume::cacheBlockNumber_; // current block number
cache_t SdVolume::cacheBuffer_; // 512 byte cache for Sd2Card
Sd2Card* SdVolume::sdCard_; // pointer to SD card object
DiskIODriver *SdVolume::sdCard_; // pointer to SD card object
bool SdVolume::cacheDirty_; // cacheFlush() will write block if true
uint32_t SdVolume::cacheMirrorBlock_; // mirror block for second FAT
#endif // USE_MULTIPLE_CARDS
#endif
// find a contiguous group of clusters
bool SdVolume::allocContiguous(uint32_t count, uint32_t *curCluster) {
@ -326,7 +326,7 @@ int32_t SdVolume::freeClusterCount() {
* Reasons for failure include not finding a valid partition, not finding a valid
* FAT file system in the specified partition or an I/O error.
*/
bool SdVolume::init(Sd2Card* dev, uint8_t part) {
bool SdVolume::init(DiskIODriver* dev, uint8_t part) {
uint32_t totalBlocks, volumeStartBlock = 0;
fat32_boot_t *fbs;

View File

@ -36,9 +36,11 @@
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#include "usb_flashdrive/Sd2Card_FlashDrive.h"
#elif ENABLED(SDIO_SUPPORT)
#endif
#if NEED_SD2CARD_SDIO
#include "Sd2Card_sdio.h"
#else
#elif NEED_SD2CARD_SPI
#include "Sd2Card.h"
#endif
@ -47,6 +49,7 @@
//==============================================================================
// SdVolume class
/**
* \brief Cache for an SD data block
*/
@ -84,14 +87,14 @@ class SdVolume {
* Initialize a FAT volume. Try partition one first then try super
* floppy format.
*
* \param[in] dev The Sd2Card where the volume is located.
* \param[in] dev The DiskIODriver where the volume is located.
*
* \return true for success, false for failure.
* Reasons for failure include not finding a valid partition, not finding
* a valid FAT file system or an I/O error.
*/
bool init(Sd2Card *dev) { return init(dev, 1) ? true : init(dev, 0); }
bool init(Sd2Card *dev, uint8_t part);
bool init(DiskIODriver *dev) { return init(dev, 1) || init(dev, 0); }
bool init(DiskIODriver *dev, uint8_t part);
// inline functions that return volume info
uint8_t blocksPerCluster() const { return blocksPerCluster_; } //> \return The volume's cluster size in blocks.
@ -112,10 +115,10 @@ class SdVolume {
uint32_t rootDirStart() const { return rootDirStart_; }
/**
* Sd2Card object for this volume
* \return pointer to Sd2Card object.
* DiskIODriver object for this volume
* \return pointer to DiskIODriver object.
*/
Sd2Card* sdCard() { return sdCard_; }
DiskIODriver* sdCard() { return sdCard_; }
/**
* Debug access to FAT table
@ -138,13 +141,13 @@ class SdVolume {
#if USE_MULTIPLE_CARDS
cache_t cacheBuffer_; // 512 byte cache for device blocks
uint32_t cacheBlockNumber_; // Logical number of block in the cache
Sd2Card *sdCard_; // Sd2Card object for cache
DiskIODriver *sdCard_; // DiskIODriver object for cache
bool cacheDirty_; // cacheFlush() will write block if true
uint32_t cacheMirrorBlock_; // block number for mirror FAT
#else
static cache_t cacheBuffer_; // 512 byte cache for device blocks
static uint32_t cacheBlockNumber_; // Logical number of block in the cache
static Sd2Card *sdCard_; // Sd2Card object for cache
static DiskIODriver *sdCard_; // DiskIODriver object for cache
static bool cacheDirty_; // cacheFlush() will write block if true
static uint32_t cacheMirrorBlock_; // block number for mirror FAT
#endif

View File

@ -120,7 +120,16 @@ uint8_t CardReader::workDirDepth;
#endif // SDCARD_SORT_ALPHA
Sd2Card CardReader::sd2card;
#if SHARED_VOLUME_IS(USB_FLASH_DRIVE) || ENABLED(USB_FLASH_DRIVE_SUPPORT)
DiskIODriver_USBFlash CardReader::media_usbFlashDrive;
#endif
#if NEED_SD2CARD_SDIO
DiskIODriver_SDIO CardReader::media_sdio;
#elif NEED_SD2CARD_SPI
DiskIODriver_SPI_SD CardReader::media_sd_spi;
#endif
DiskIODriver* CardReader::driver = nullptr;
SdVolume CardReader::volume;
SdFile CardReader::file;
@ -133,6 +142,16 @@ SdFile CardReader::file;
uint32_t CardReader::filesize, CardReader::sdpos;
CardReader::CardReader() {
changeMedia(&
#if SHARED_VOLUME_IS(SD_ONBOARD)
media_sd_spi
#elif SHARED_VOLUME_IS(USB_FLASH_DRIVE) || ENABLED(USB_FLASH_DRIVE_SUPPORT)
media_usbFlashDrive
#else
TERN(SDIO_SUPPORT, media_sdio, media_sd_spi)
#endif
);
#if ENABLED(SDCARD_SORT_ALPHA)
sort_count = 0;
#if ENABLED(SDSORT_GCODE)
@ -383,12 +402,12 @@ void CardReader::mount() {
flag.mounted = false;
if (root.isOpen()) root.close();
if (!sd2card.init(SD_SPI_SPEED, SDSS)
if (!driver->init(SD_SPI_SPEED, SDSS)
#if defined(LCD_SDSS) && (LCD_SDSS != SDSS)
&& !sd2card.init(SD_SPI_SPEED, LCD_SDSS)
&& !driver->init(SD_SPI_SPEED, LCD_SDSS)
#endif
) SERIAL_ECHO_MSG(STR_SD_INIT_FAIL);
else if (!volume.init(&sd2card))
else if (!volume.init(driver))
SERIAL_ERROR_MSG(STR_SD_VOL_INIT_FAIL);
else if (!root.openRoot(&volume))
SERIAL_ERROR_MSG(STR_SD_OPENROOT_FAIL);

View File

@ -42,6 +42,29 @@ extern const char M23_STR[], M24_STR[];
#define MAXPATHNAMELENGTH (1 + (MAXDIRNAMELENGTH + 1) * (MAX_DIR_DEPTH) + 1 + FILENAME_LENGTH) // "/" + N * ("ADIRNAME/") + "filename.ext"
#include "SdFile.h"
#include "disk_io_driver.h"
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#include "usb_flashdrive/Sd2Card_FlashDrive.h"
#endif
#if NEED_SD2CARD_SDIO
#include "Sd2Card_sdio.h"
#elif NEED_SD2CARD_SPI
#include "Sd2Card.h"
#endif
#if ENABLED(MULTI_VOLUME)
#define SV_SD_ONBOARD 1
#define SV_USB_FLASH_DRIVE 2
#define _VOLUME_ID(N) _CAT(SV_, N)
#define SHARED_VOLUME_IS(N) (DEFAULT_SHARED_VOLUME == _VOLUME_ID(N))
#if !SHARED_VOLUME_IS(SD_ONBOARD) && !SHARED_VOLUME_IS(USB_FLASH_DRIVE)
#error "DEFAULT_SHARED_VOLUME must be either SD_ONBOARD or USB_FLASH_DRIVE."
#endif
#else
#define SHARED_VOLUME_IS(...) 0
#endif
typedef struct {
bool saving:1,
@ -80,6 +103,8 @@ public:
CardReader();
static void changeMedia(DiskIODriver *_driver) { driver = _driver; }
static SdFile getroot() { return root; }
static void mount();
@ -171,7 +196,8 @@ public:
static inline int16_t read(void *buf, uint16_t nbyte) { return file.isOpen() ? file.read(buf, nbyte) : -1; }
static inline int16_t write(void *buf, uint16_t nbyte) { return file.isOpen() ? file.write(buf, nbyte) : -1; }
static Sd2Card& getSd2Card() { return sd2card; }
// TODO: rename to diskIODriver()
static DiskIODriver* diskIODriver() { return driver; }
#if ENABLED(AUTO_REPORT_SD_STATUS)
//
@ -181,6 +207,15 @@ public:
static AutoReporter<AutoReportSD> auto_reporter;
#endif
#if SHARED_VOLUME_IS(USB_FLASH_DRIVE) || ENABLED(USB_FLASH_DRIVE_SUPPORT)
static DiskIODriver_USBFlash media_usbFlashDrive;
#endif
#if NEED_SD2CARD_SDIO
static DiskIODriver_SDIO media_sdio;
#elif NEED_SD2CARD_SPI
static DiskIODriver_SPI_SD media_sd_spi;
#endif
private:
//
// Working directory and parents
@ -236,7 +271,7 @@ private:
#if ENABLED(SDSORT_DYNAMIC_RAM)
static uint8_t *isDir;
#elif ENABLED(SDSORT_CACHE_NAMES) || DISABLED(SDSORT_USES_STACK)
static uint8_t isDir[(SDSORT_LIMIT+7)>>3];
static uint8_t isDir[(SDSORT_LIMIT + 7) >> 3];
#endif
#endif
@ -244,7 +279,7 @@ private:
#endif // SDCARD_SORT_ALPHA
static Sd2Card sd2card;
static DiskIODriver *driver;
static SdVolume volume;
static SdFile file;
@ -275,7 +310,7 @@ private:
};
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
#define IS_SD_INSERTED() Sd2Card::isInserted()
#define IS_SD_INSERTED() DiskIODriver_USBFlash::isInserted()
#elif PIN_EXISTS(SD_DETECT)
#define IS_SD_INSERTED() (READ(SD_DETECT_PIN) == SD_DETECT_STATE)
#else

View File

@ -0,0 +1,67 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2021 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/>.
*
*/
#pragma once
#include <stdint.h>
/**
* DiskIO Interace
*
* Interface for low level disk io
*/
class DiskIODriver {
public:
/**
* Initialize an SD flash memory card with default clock rate and chip
* select pin. See sd2Card::init(uint8_t sckRateID, uint8_t chipSelectPin).
*
* \return true for success or false for failure.
*/
virtual bool init(const uint8_t sckRateID, const pin_t chipSelectPin) = 0; //TODO: only for SPI
/**
* Read a card's CSD register. The CSD contains Card-Specific Data that
* provides information regarding access to the card's contents.
*
* \param[out] csd pointer to area for returned data.
*
* \return true for success or false for failure.
*/
virtual bool readCSD(csd_t* csd) = 0;
virtual bool readStart(const uint32_t block) = 0;
virtual bool readData(uint8_t* dst) = 0;
virtual bool readStop() = 0;
virtual bool writeStart(const uint32_t block, const uint32_t) = 0;
virtual bool writeData(const uint8_t* src) = 0;
virtual bool writeStop() = 0;
virtual bool readBlock(uint32_t block, uint8_t* dst) = 0;
virtual bool writeBlock(uint32_t blockNumber, const uint8_t* src) = 0;
virtual uint32_t cardSize() = 0;
virtual bool isReady() = 0;
virtual void idle() = 0;
};

View File

@ -121,7 +121,7 @@ static enum {
uint32_t lun0_capacity;
#endif
bool Sd2Card::usbStartup() {
bool DiskIODriver_USBFlash::usbStartup() {
if (state <= DO_STARTUP) {
SERIAL_ECHOPGM("Starting USB host...");
if (!UHS_START) {
@ -147,7 +147,7 @@ bool Sd2Card::usbStartup() {
// the USB library to monitor for such events. This function also takes care
// of initializing the USB library for the first time.
void Sd2Card::idle() {
void DiskIODriver_USBFlash::idle() {
usb.Task();
const uint8_t task_state = usb.getUsbTaskState();
@ -258,16 +258,16 @@ void Sd2Card::idle() {
// Marlin calls this function to check whether an USB drive is inserted.
// This is equivalent to polling the SD_DETECT when using SD cards.
bool Sd2Card::isInserted() {
bool DiskIODriver_USBFlash::isInserted() {
return state == MEDIA_READY;
}
bool Sd2Card::isReady() {
return state > DO_STARTUP;
bool DiskIODriver_USBFlash::isReady() {
return state > DO_STARTUP && usb.getUsbTaskState() == UHS_STATE(RUNNING);
}
// Marlin calls this to initialize an SD card once it is inserted.
bool Sd2Card::init(const uint8_t, const pin_t) {
bool DiskIODriver_USBFlash::init(const uint8_t, const pin_t) {
if (!isInserted()) return false;
#if USB_DEBUG >= 1
@ -286,7 +286,7 @@ bool Sd2Card::init(const uint8_t, const pin_t) {
}
// Returns the capacity of the card in blocks.
uint32_t Sd2Card::cardSize() {
uint32_t DiskIODriver_USBFlash::cardSize() {
if (!isInserted()) return false;
#if USB_DEBUG < 3
const uint32_t
@ -295,7 +295,7 @@ uint32_t Sd2Card::cardSize() {
return lun0_capacity;
}
bool Sd2Card::readBlock(uint32_t block, uint8_t *dst) {
bool DiskIODriver_USBFlash::readBlock(uint32_t block, uint8_t *dst) {
if (!isInserted()) return false;
#if USB_DEBUG >= 3
if (block >= lun0_capacity) {
@ -309,7 +309,7 @@ bool Sd2Card::readBlock(uint32_t block, uint8_t *dst) {
return bulk.Read(0, block, 512, 1, dst) == 0;
}
bool Sd2Card::writeBlock(uint32_t block, const uint8_t *src) {
bool DiskIODriver_USBFlash::writeBlock(uint32_t block, const uint8_t *src) {
if (!isInserted()) return false;
#if USB_DEBUG >= 3
if (block >= lun0_capacity) {

View File

@ -27,6 +27,7 @@
*/
#include "../SdFatConfig.h"
#include "../SdInfo.h"
#include "../disk_io_driver.h"
#if DISABLED(USE_OTG_USB_HOST)
/**
@ -46,7 +47,7 @@
#endif
#endif
class Sd2Card {
class DiskIODriver_USBFlash : public DiskIODriver {
private:
uint32_t pos;
@ -54,25 +55,26 @@ class Sd2Card {
public:
static bool usbStartup();
bool init(const uint8_t sckRateID=0, const pin_t chipSelectPin=TERN(USE_OTG_USB_HOST, 0, SD_CHIP_SELECT_PIN));
static void idle();
inline bool readStart(const uint32_t block) { pos = block; return isReady(); }
inline bool readData(uint8_t *dst) { return readBlock(pos++, dst); }
inline bool readStop() const { return true; }
inline bool writeStart(const uint32_t block, const uint32_t) { pos = block; return isReady(); }
inline bool writeData(uint8_t *src) { return writeBlock(pos++, src); }
inline bool writeStop() const { return true; }
bool readBlock(uint32_t block, uint8_t *dst);
bool writeBlock(uint32_t blockNumber, const uint8_t *src);
bool readCSD(csd_t*) { return true; }
uint32_t cardSize();
static bool isInserted();
bool isReady();
bool init(const uint8_t sckRateID=0, const pin_t chipSelectPin=TERN(USE_OTG_USB_HOST, 0, SD_CHIP_SELECT_PIN)) override;
inline bool readCSD(csd_t*) override { return true; }
inline bool readStart(const uint32_t block) override { pos = block; return isReady(); }
inline bool readData(uint8_t *dst) override { return readBlock(pos++, dst); }
inline bool readStop() override { return true; }
inline bool writeStart(const uint32_t block, const uint32_t) override { pos = block; return isReady(); }
inline bool writeData(const uint8_t *src) override { return writeBlock(pos++, src); }
inline bool writeStop() override { return true; }
bool readBlock(uint32_t block, uint8_t *dst) override;
bool writeBlock(uint32_t blockNumber, const uint8_t *src) override;
uint32_t cardSize() override;
bool isReady() override;
void idle() override;
};