update code base to Marlin 2.0.9.2
This commit is contained in:
112
Marlin/src/sd/Sd2Card.cpp
Executable file → Normal file
112
Marlin/src/sd/Sd2Card.cpp
Executable file → Normal file
@@ -16,7 +16,7 @@
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -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 */
|
||||
@@ -63,7 +63,7 @@
|
||||
0x0E,0x07,0x1C,0x15,0x2A,0x23,0x38,0x31,0x46,0x4F,0x54,0x5D,0x62,0x6B,0x70,0x79
|
||||
};
|
||||
|
||||
static uint8_t CRC7(const uint8_t* data, uint8_t n) {
|
||||
static uint8_t CRC7(const uint8_t *data, uint8_t n) {
|
||||
uint8_t crc = 0;
|
||||
while (n > 0) {
|
||||
crc = pgm_read_byte(&crctab7[ (crc << 1) ^ *data++ ]);
|
||||
@@ -72,7 +72,7 @@
|
||||
return (crc << 1) | 1;
|
||||
}
|
||||
#else
|
||||
static uint8_t CRC7(const uint8_t* data, uint8_t n) {
|
||||
static uint8_t CRC7(const uint8_t *data, uint8_t n) {
|
||||
uint8_t crc = 0;
|
||||
LOOP_L_N(i, n) {
|
||||
uint8_t d = data[i];
|
||||
@@ -88,7 +88,12 @@
|
||||
#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) {
|
||||
|
||||
#if ENABLED(SDCARD_COMMANDS_SPLIT)
|
||||
if (cmd != CMD12) chipDeselect();
|
||||
#endif
|
||||
|
||||
// Select card
|
||||
chipSelect();
|
||||
|
||||
@@ -133,7 +138,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 +160,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,9 +183,12 @@ 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;
|
||||
if (!readCSD(&csd)) goto FAIL;
|
||||
|
||||
// check for single block erase
|
||||
if (!csd.v1.erase_blk_en) {
|
||||
// erase size mask
|
||||
@@ -213,7 +221,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;
|
||||
}
|
||||
@@ -227,7 +235,14 @@ 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();
|
||||
type_ = SDHC_CardGetType();
|
||||
return (ret == 0);
|
||||
#endif
|
||||
|
||||
errorCode_ = type_ = 0;
|
||||
chipSelectPin_ = chipSelectPin;
|
||||
// 16-bit init start time allows over a minute
|
||||
@@ -237,8 +252,15 @@ bool Sd2Card::init(const uint8_t sckRateID, const pin_t chipSelectPin) {
|
||||
watchdog_refresh(); // In case init takes too long
|
||||
|
||||
// Set pin modes
|
||||
extDigitalWrite(chipSelectPin_, HIGH); // For some CPUs pinMode can write the wrong data so init desired data value first
|
||||
pinMode(chipSelectPin_, OUTPUT); // Solution for #8746 by @benlye
|
||||
#if ENABLED(ZONESTAR_12864OLED)
|
||||
if (chipSelectPin_ != DOGLCD_CS) {
|
||||
SET_OUTPUT(DOGLCD_CS);
|
||||
WRITE(DOGLCD_CS, HIGH);
|
||||
}
|
||||
#else
|
||||
extDigitalWrite(chipSelectPin_, HIGH); // For some CPUs pinMode can write the wrong data so init desired data value first
|
||||
pinMode(chipSelectPin_, OUTPUT); // Solution for #8746 by @benlye
|
||||
#endif
|
||||
spiBegin();
|
||||
|
||||
// Set SCK rate for initialization commands
|
||||
@@ -307,10 +329,12 @@ bool Sd2Card::init(const uint8_t sckRateID, const pin_t chipSelectPin) {
|
||||
}
|
||||
chipDeselect();
|
||||
|
||||
ready = true;
|
||||
return setSckRate(sckRateID);
|
||||
|
||||
FAIL:
|
||||
chipDeselect();
|
||||
ready = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -321,7 +345,11 @@ 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
|
||||
|
||||
if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9; // Use address if not SDHC card
|
||||
|
||||
#if ENABLED(SD_CHECK_AND_RETRY)
|
||||
@@ -357,7 +385,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);
|
||||
}
|
||||
@@ -400,7 +428,7 @@ bool Sd2Card::readData(uint8_t* dst) {
|
||||
};
|
||||
// faster CRC-CCITT
|
||||
// uses the x^16,x^12,x^5,x^1 polynomial.
|
||||
static uint16_t CRC_CCITT(const uint8_t* data, size_t n) {
|
||||
static uint16_t CRC_CCITT(const uint8_t *data, size_t n) {
|
||||
uint16_t crc = 0;
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
crc = pgm_read_word(&crctab16[(crc >> 8 ^ data[i]) & 0xFF]) ^ (crc << 8);
|
||||
@@ -410,7 +438,7 @@ bool Sd2Card::readData(uint8_t* dst) {
|
||||
#else
|
||||
// slower CRC-CCITT
|
||||
// uses the x^16,x^12,x^5,x^1 polynomial.
|
||||
static uint16_t CRC_CCITT(const uint8_t* data, size_t n) {
|
||||
static uint16_t CRC_CCITT(const uint8_t *data, size_t n) {
|
||||
uint16_t crc = 0;
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
crc = (uint8_t)(crc >> 8) | (crc << 8);
|
||||
@@ -424,7 +452,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;
|
||||
@@ -456,8 +484,8 @@ bool Sd2Card::readData(uint8_t* dst, const uint16_t count) {
|
||||
}
|
||||
|
||||
/** read CID or CSR register */
|
||||
bool Sd2Card::readRegister(const uint8_t cmd, void* buf) {
|
||||
uint8_t* dst = reinterpret_cast<uint8_t*>(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);
|
||||
chipDeselect();
|
||||
@@ -476,7 +504,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);
|
||||
@@ -490,7 +518,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);
|
||||
@@ -510,7 +538,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;
|
||||
@@ -521,12 +549,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.
|
||||
*
|
||||
@@ -534,10 +564,15 @@ 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) {
|
||||
if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9; // Use address if not SDHC card
|
||||
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
|
||||
return 0 == SDHC_CardWriteBlock(src, blockNumber);
|
||||
#endif
|
||||
|
||||
bool success = false;
|
||||
if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9; // Use address if not SDHC card
|
||||
if (!cardCommand(CMD24, blockNumber)) {
|
||||
if (writeData(DATA_START_BLOCK, src)) {
|
||||
if (waitNotBusy(SD_WRITE_TIMEOUT)) { // Wait for flashing to complete
|
||||
@@ -560,7 +595,9 @@ 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;
|
||||
chipSelect();
|
||||
// Wait for previous write to finish
|
||||
@@ -573,15 +610,10 @@ 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;
|
||||
|
||||
uint16_t crc =
|
||||
#if ENABLED(SD_CHECK_AND_RETRY)
|
||||
CRC_CCITT(src, 512)
|
||||
#else
|
||||
0xFFFF
|
||||
#endif
|
||||
;
|
||||
const uint16_t crc = TERN(SD_CHECK_AND_RETRY, CRC_CCITT(src, 512), 0xFFFF);
|
||||
spiSendBlock(token, src);
|
||||
spiSend(crc >> 8);
|
||||
spiSend(crc & 0xFF);
|
||||
@@ -606,7 +638,9 @@ 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;
|
||||
if (!cardAcmd(ACMD23, eraseCount)) { // Send pre-erase count
|
||||
if (type() != SD_CARD_TYPE_SDHC) blockNumber <<= 9; // Use address if not SDHC card
|
||||
@@ -625,7 +659,9 @@ 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;
|
||||
chipSelect();
|
||||
if (waitNotBusy(SD_WRITE_TIMEOUT)) {
|
||||
@@ -639,4 +675,4 @@ bool Sd2Card::writeStop() {
|
||||
return success;
|
||||
}
|
||||
|
||||
#endif // SDSUPPORT
|
||||
#endif // NEED_SD2CARD_SPI
|
||||
|
142
Marlin/src/sd/Sd2Card.h
Executable file → Normal file
142
Marlin/src/sd/Sd2Card.h
Executable file → Normal file
@@ -16,7 +16,7 @@
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
@@ -35,67 +35,72 @@
|
||||
|
||||
#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
|
||||
* Define SOFTWARE_SPI to use bit-bang SPI
|
||||
*/
|
||||
#if MEGA_SOFT_SPI
|
||||
#if EITHER(MEGA_SOFT_SPI, USE_SOFTWARE_SPI)
|
||||
#define SOFTWARE_SPI
|
||||
#elif USE_SOFTWARE_SPI
|
||||
#define SOFTWARE_SPI
|
||||
#endif // MEGA_SOFT_SPI
|
||||
#endif
|
||||
|
||||
#if IS_TEENSY_35_36 || IS_TEENSY_40_41
|
||||
#include "NXP_SDHC.h"
|
||||
#define BUILTIN_SDCARD 254
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \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();
|
||||
|
||||
@@ -103,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.
|
||||
@@ -119,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
|
||||
@@ -132,7 +143,7 @@ public:
|
||||
*
|
||||
* \return true for success or false for failure.
|
||||
*/
|
||||
bool readCID(cid_t* cid) { return readRegister(CMD10, cid); }
|
||||
bool readCID(cid_t *cid) { return readRegister(CMD10, cid); }
|
||||
|
||||
/**
|
||||
* Read a card's CSD register. The CSD contains Card-Specific Data that
|
||||
@@ -142,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_,
|
||||
@@ -173,11 +187,11 @@ private:
|
||||
}
|
||||
uint8_t cardCommand(const uint8_t cmd, const uint32_t arg);
|
||||
|
||||
bool readData(uint8_t* dst, const uint16_t count);
|
||||
bool readRegister(const uint8_t cmd, void* buf);
|
||||
bool readData(uint8_t *dst, const uint16_t count);
|
||||
bool readRegister(const uint8_t cmd, void *buf);
|
||||
void chipDeselect();
|
||||
void chipSelect();
|
||||
inline void type(const uint8_t value) { type_ = value; }
|
||||
bool waitNotBusy(const millis_t timeout_ms);
|
||||
bool writeData(const uint8_t token, const uint8_t* src);
|
||||
bool writeData(const uint8_t token, const uint8_t *src);
|
||||
};
|
||||
|
36
Marlin/src/sd/Sd2Card_sdio.h
Executable file → Normal file
36
Marlin/src/sd/Sd2Card_sdio.h
Executable file → Normal file
@@ -16,24 +16,44 @@
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#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);
|
||||
bool SDIO_IsReady();
|
||||
uint32_t SDIO_GetCardSize();
|
||||
|
||||
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 { curBlock = block; return true; }
|
||||
bool readData(uint8_t *dst) override { return readBlock(curBlock++, dst); }
|
||||
bool readStop() override { curBlock = -1; return true; }
|
||||
|
||||
bool writeStart(const uint32_t block, const uint32_t) override { curBlock = block; return true; }
|
||||
bool writeData(const uint8_t *src) override { return writeBlock(curBlock++, src); }
|
||||
bool writeStop() override { curBlock = -1; return true; }
|
||||
|
||||
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 SDIO_GetCardSize(); }
|
||||
|
||||
bool isReady() override { return SDIO_IsReady(); }
|
||||
|
||||
void idle() override {}
|
||||
private:
|
||||
uint32_t curBlock;
|
||||
};
|
||||
|
290
Marlin/src/sd/SdBaseFile.cpp
Executable file → Normal file
290
Marlin/src/sd/SdBaseFile.cpp
Executable file → Normal file
@@ -16,17 +16,17 @@
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#if __GNUC__ > 8
|
||||
// The NXP platform updated GCC from 7.2.1 to 9.2.1
|
||||
// and this new warning apparently can be ignored.
|
||||
#pragma GCC diagnostic ignored "-Waddress-of-packed-member"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* sd/SdBaseFile.cpp
|
||||
*
|
||||
* Arduino SdFat Library
|
||||
* Copyright (c) 2009 by William Greiman
|
||||
*
|
||||
@@ -40,13 +40,15 @@
|
||||
#include "SdBaseFile.h"
|
||||
|
||||
#include "../MarlinCore.h"
|
||||
SdBaseFile* SdBaseFile::cwd_ = 0; // Pointer to Current Working Directory
|
||||
SdBaseFile *SdBaseFile::cwd_ = 0; // Pointer to Current Working Directory
|
||||
|
||||
// callback function for date/time
|
||||
void (*SdBaseFile::dateTime_)(uint16_t* date, uint16_t* time) = 0;
|
||||
void (*SdBaseFile::dateTime_)(uint16_t *date, uint16_t *time) = 0;
|
||||
|
||||
// add a cluster to a file
|
||||
bool SdBaseFile::addCluster() {
|
||||
if (ENABLED(SDCARD_READONLY)) return false;
|
||||
|
||||
if (!vol_->allocContiguous(1, &curCluster_)) return false;
|
||||
|
||||
// if first cluster of file link to directory entry
|
||||
@@ -60,6 +62,8 @@ bool SdBaseFile::addCluster() {
|
||||
// Add a cluster to a directory file and zero the cluster.
|
||||
// return with first block of cluster in the cache
|
||||
bool SdBaseFile::addDirCluster() {
|
||||
if (ENABLED(SDCARD_READONLY)) return false;
|
||||
|
||||
uint32_t block;
|
||||
// max folder size
|
||||
if (fileSize_ / sizeof(dir_t) >= 0xFFFF) return false;
|
||||
@@ -114,7 +118,7 @@ bool SdBaseFile::close() {
|
||||
* Reasons for failure include file is not contiguous, file has zero length
|
||||
* or an I/O error occurred.
|
||||
*/
|
||||
bool SdBaseFile::contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock) {
|
||||
bool SdBaseFile::contiguousRange(uint32_t *bgnBlock, uint32_t *endBlock) {
|
||||
// error if no blocks
|
||||
if (firstCluster_ == 0) return false;
|
||||
|
||||
@@ -150,9 +154,10 @@ bool SdBaseFile::contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock) {
|
||||
* an invalid DOS 8.3 file name, the FAT volume has not been initialized,
|
||||
* a file is already open, the file already exists, the root
|
||||
* directory is full or an I/O error.
|
||||
*
|
||||
*/
|
||||
bool SdBaseFile::createContiguous(SdBaseFile* dirFile, const char* path, uint32_t size) {
|
||||
bool SdBaseFile::createContiguous(SdBaseFile *dirFile, const char *path, uint32_t size) {
|
||||
if (ENABLED(SDCARD_READONLY)) return false;
|
||||
|
||||
uint32_t count;
|
||||
// don't allow zero length file
|
||||
if (size == 0) return false;
|
||||
@@ -181,13 +186,12 @@ bool SdBaseFile::createContiguous(SdBaseFile* dirFile, const char* path, uint32_
|
||||
*
|
||||
* \return true for success, false for failure.
|
||||
*/
|
||||
bool SdBaseFile::dirEntry(dir_t* dir) {
|
||||
dir_t* p;
|
||||
bool SdBaseFile::dirEntry(dir_t *dir) {
|
||||
// make sure fields on SD are correct
|
||||
if (!sync()) return false;
|
||||
|
||||
// read entry
|
||||
p = cacheDirEntry(SdVolume::CACHE_FOR_READ);
|
||||
dir_t *p = cacheDirEntry(SdVolume::CACHE_FOR_READ);
|
||||
if (!p) return false;
|
||||
|
||||
// copy to caller's struct
|
||||
@@ -202,7 +206,7 @@ bool SdBaseFile::dirEntry(dir_t* dir) {
|
||||
* \param[in] dir The directory structure containing the name.
|
||||
* \param[out] name A 13 byte char array for the formatted name.
|
||||
*/
|
||||
void SdBaseFile::dirName(const dir_t& dir, char* name) {
|
||||
void SdBaseFile::dirName(const dir_t &dir, char *name) {
|
||||
uint8_t j = 0;
|
||||
LOOP_L_N(i, 11) {
|
||||
if (dir.name[i] == ' ')continue;
|
||||
@@ -224,7 +228,7 @@ void SdBaseFile::dirName(const dir_t& dir, char* name) {
|
||||
*
|
||||
* \return true if the file exists else false.
|
||||
*/
|
||||
bool SdBaseFile::exists(const char* name) {
|
||||
bool SdBaseFile::exists(const char *name) {
|
||||
SdBaseFile file;
|
||||
return file.open(this, name, O_READ);
|
||||
}
|
||||
@@ -249,7 +253,7 @@ bool SdBaseFile::exists(const char* name) {
|
||||
* \return For success fgets() returns the length of the string in \a str.
|
||||
* If no data is read, fgets() returns zero for EOF or -1 if an error occurred.
|
||||
**/
|
||||
int16_t SdBaseFile::fgets(char* str, int16_t num, char* delim) {
|
||||
int16_t SdBaseFile::fgets(char *str, int16_t num, char *delim) {
|
||||
char ch;
|
||||
int16_t n = 0;
|
||||
int16_t r = -1;
|
||||
@@ -288,7 +292,7 @@ bool SdBaseFile::getDosName(char * const name) {
|
||||
return true;
|
||||
}
|
||||
// cache entry
|
||||
dir_t* p = cacheDirEntry(SdVolume::CACHE_FOR_READ);
|
||||
dir_t *p = cacheDirEntry(SdVolume::CACHE_FOR_READ);
|
||||
if (!p) return false;
|
||||
|
||||
// format name
|
||||
@@ -296,7 +300,7 @@ bool SdBaseFile::getDosName(char * const name) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void SdBaseFile::getpos(filepos_t* pos) {
|
||||
void SdBaseFile::getpos(filepos_t *pos) {
|
||||
pos->position = curPosition_;
|
||||
pos->cluster = curCluster_;
|
||||
}
|
||||
@@ -381,7 +385,7 @@ int8_t SdBaseFile::lsPrintNext(uint8_t flags, uint8_t indent) {
|
||||
}
|
||||
|
||||
// Format directory name field from a 8.3 name string
|
||||
bool SdBaseFile::make83Name(const char* str, uint8_t* name, const char** ptr) {
|
||||
bool SdBaseFile::make83Name(const char *str, uint8_t *name, const char **ptr) {
|
||||
uint8_t n = 7, // Max index until a dot is found
|
||||
i = 11;
|
||||
while (i) name[--i] = ' '; // Set whole FILENAME.EXT to spaces
|
||||
@@ -396,8 +400,8 @@ bool SdBaseFile::make83Name(const char* str, uint8_t* name, const char** ptr) {
|
||||
// Fail for illegal characters
|
||||
PGM_P p = PSTR("|<>^+=?/[];,*\"\\");
|
||||
while (uint8_t b = pgm_read_byte(p++)) if (b == c) return false;
|
||||
if (i > n || c < 0x21 || c == 0x7F) return false; // Check size, non-printable characters
|
||||
name[i++] = (c < 'a' || c > 'z') ? (c) : (c + ('A' - 'a')); // Uppercase required for 8.3 name
|
||||
if (i > n || c < 0x21 || c == 0x7F) return false; // Check size, non-printable characters
|
||||
name[i++] = c + (WITHIN(c, 'a', 'z') ? 'A' - 'a' : 0); // Uppercase required for 8.3 name
|
||||
}
|
||||
}
|
||||
*ptr = str; // Set passed pointer to the end
|
||||
@@ -418,11 +422,13 @@ bool SdBaseFile::make83Name(const char* str, uint8_t* name, const char** ptr) {
|
||||
* Reasons for failure include this file is already open, \a parent is not a
|
||||
* directory, \a path is invalid or already exists in \a parent.
|
||||
*/
|
||||
bool SdBaseFile::mkdir(SdBaseFile* parent, const char* path, bool pFlag) {
|
||||
bool SdBaseFile::mkdir(SdBaseFile *parent, const char *path, bool pFlag) {
|
||||
if (ENABLED(SDCARD_READONLY)) return false;
|
||||
|
||||
uint8_t dname[11];
|
||||
SdBaseFile dir1, dir2;
|
||||
SdBaseFile* sub = &dir1;
|
||||
SdBaseFile* start = parent;
|
||||
SdBaseFile *sub = &dir1;
|
||||
SdBaseFile *start = parent;
|
||||
|
||||
if (!parent || isOpen()) return false;
|
||||
|
||||
@@ -448,10 +454,8 @@ bool SdBaseFile::mkdir(SdBaseFile* parent, const char* path, bool pFlag) {
|
||||
return mkdir(parent, dname);
|
||||
}
|
||||
|
||||
bool SdBaseFile::mkdir(SdBaseFile* parent, const uint8_t dname[11]) {
|
||||
uint32_t block;
|
||||
dir_t d;
|
||||
dir_t* p;
|
||||
bool SdBaseFile::mkdir(SdBaseFile *parent, const uint8_t dname[11]) {
|
||||
if (ENABLED(SDCARD_READONLY)) return false;
|
||||
|
||||
if (!parent->isDir()) return false;
|
||||
|
||||
@@ -469,19 +473,20 @@ bool SdBaseFile::mkdir(SdBaseFile* parent, const uint8_t dname[11]) {
|
||||
if (!sync()) return false;
|
||||
|
||||
// cache entry - should already be in cache due to sync() call
|
||||
p = cacheDirEntry(SdVolume::CACHE_FOR_WRITE);
|
||||
dir_t *p = cacheDirEntry(SdVolume::CACHE_FOR_WRITE);
|
||||
if (!p) return false;
|
||||
|
||||
// change directory entry attribute
|
||||
p->attributes = DIR_ATT_DIRECTORY;
|
||||
|
||||
// make entry for '.'
|
||||
dir_t d;
|
||||
memcpy(&d, p, sizeof(d));
|
||||
d.name[0] = '.';
|
||||
LOOP_S_L_N(i, 1, 11) d.name[i] = ' ';
|
||||
|
||||
// cache block for '.' and '..'
|
||||
block = vol_->clusterStartBlock(firstCluster_);
|
||||
uint32_t block = vol_->clusterStartBlock(firstCluster_);
|
||||
if (!vol_->cacheRawBlock(block, SdVolume::CACHE_FOR_WRITE)) return false;
|
||||
|
||||
// copy '.' to block
|
||||
@@ -514,7 +519,7 @@ bool SdBaseFile::mkdir(SdBaseFile* parent, const uint8_t dname[11]) {
|
||||
*
|
||||
* \return true for success, false for failure.
|
||||
*/
|
||||
bool SdBaseFile::open(const char* path, uint8_t oflag) {
|
||||
bool SdBaseFile::open(const char *path, uint8_t oflag) {
|
||||
return open(cwd_, path, oflag);
|
||||
}
|
||||
|
||||
@@ -568,7 +573,7 @@ bool SdBaseFile::open(const char* path, uint8_t oflag) {
|
||||
* a directory, \a path is invalid, the file does not exist
|
||||
* or can't be opened in the access mode specified by oflag.
|
||||
*/
|
||||
bool SdBaseFile::open(SdBaseFile* dirFile, const char* path, uint8_t oflag) {
|
||||
bool SdBaseFile::open(SdBaseFile *dirFile, const char *path, uint8_t oflag) {
|
||||
uint8_t dname[11];
|
||||
SdBaseFile dir1, dir2;
|
||||
SdBaseFile *parent = dirFile, *sub = &dir1;
|
||||
@@ -596,10 +601,10 @@ bool SdBaseFile::open(SdBaseFile* dirFile, const char* path, uint8_t oflag) {
|
||||
}
|
||||
|
||||
// open with filename in dname
|
||||
bool SdBaseFile::open(SdBaseFile* dirFile, const uint8_t dname[11], uint8_t oflag) {
|
||||
bool SdBaseFile::open(SdBaseFile *dirFile, const uint8_t dname[11], uint8_t oflag) {
|
||||
bool emptyFound = false, fileFound = false;
|
||||
uint8_t index;
|
||||
dir_t* p;
|
||||
dir_t *p;
|
||||
|
||||
vol_ = dirFile->vol_;
|
||||
|
||||
@@ -632,7 +637,7 @@ bool SdBaseFile::open(SdBaseFile* dirFile, const uint8_t dname[11], uint8_t ofla
|
||||
}
|
||||
else {
|
||||
// don't create unless O_CREAT and O_WRITE
|
||||
if (!(oflag & O_CREAT) || !(oflag & O_WRITE)) return false;
|
||||
if ((oflag & (O_CREAT | O_WRITE)) != (O_CREAT | O_WRITE)) return false;
|
||||
if (emptyFound) {
|
||||
index = dirIndex_;
|
||||
p = cacheDirEntry(SdVolume::CACHE_FOR_WRITE);
|
||||
@@ -687,9 +692,7 @@ bool SdBaseFile::open(SdBaseFile* dirFile, const uint8_t dname[11], uint8_t ofla
|
||||
* See open() by path for definition of flags.
|
||||
* \return true for success or false for failure.
|
||||
*/
|
||||
bool SdBaseFile::open(SdBaseFile* dirFile, uint16_t index, uint8_t oflag) {
|
||||
dir_t* p;
|
||||
|
||||
bool SdBaseFile::open(SdBaseFile *dirFile, uint16_t index, uint8_t oflag) {
|
||||
vol_ = dirFile->vol_;
|
||||
|
||||
// error if already open
|
||||
@@ -702,7 +705,7 @@ bool SdBaseFile::open(SdBaseFile* dirFile, uint16_t index, uint8_t oflag) {
|
||||
if (!dirFile->seekSet(32 * index)) return false;
|
||||
|
||||
// read entry into cache
|
||||
p = dirFile->readDirCache();
|
||||
dir_t *p = dirFile->readDirCache();
|
||||
if (!p) return false;
|
||||
|
||||
// error if empty slot or '.' or '..'
|
||||
@@ -716,8 +719,14 @@ bool SdBaseFile::open(SdBaseFile* dirFile, uint16_t index, uint8_t oflag) {
|
||||
|
||||
// open a cached directory entry. Assumes vol_ is initialized
|
||||
bool SdBaseFile::openCachedEntry(uint8_t dirIndex, uint8_t oflag) {
|
||||
dir_t *p;
|
||||
|
||||
#if ENABLED(SDCARD_READONLY)
|
||||
if (oflag & (O_WRITE | O_CREAT | O_TRUNC)) goto FAIL;
|
||||
#endif
|
||||
|
||||
// location of entry in cache
|
||||
dir_t* p = &vol_->cache()->dir[dirIndex];
|
||||
p = &vol_->cache()->dir[dirIndex];
|
||||
|
||||
// write or truncate is an error for a directory or read-only file
|
||||
if (p->attributes & (DIR_ATT_READ_ONLY | DIR_ATT_DIRECTORY)) {
|
||||
@@ -769,10 +778,7 @@ bool SdBaseFile::openCachedEntry(uint8_t dirIndex, uint8_t oflag) {
|
||||
* See open() by path for definition of flags.
|
||||
* \return true for success or false for failure.
|
||||
*/
|
||||
bool SdBaseFile::openNext(SdBaseFile* dirFile, uint8_t oflag) {
|
||||
dir_t* p;
|
||||
uint8_t index;
|
||||
|
||||
bool SdBaseFile::openNext(SdBaseFile *dirFile, uint8_t oflag) {
|
||||
if (!dirFile) return false;
|
||||
|
||||
// error if already open
|
||||
@@ -781,10 +787,10 @@ bool SdBaseFile::openNext(SdBaseFile* dirFile, uint8_t oflag) {
|
||||
vol_ = dirFile->vol_;
|
||||
|
||||
while (1) {
|
||||
index = 0xF & (dirFile->curPosition_ >> 5);
|
||||
uint8_t index = 0xF & (dirFile->curPosition_ >> 5);
|
||||
|
||||
// read entry into cache
|
||||
p = dirFile->readDirCache();
|
||||
dir_t *p = dirFile->readDirCache();
|
||||
if (!p) return false;
|
||||
|
||||
// done if last entry
|
||||
@@ -810,9 +816,8 @@ bool SdBaseFile::openNext(SdBaseFile* dirFile, uint8_t oflag) {
|
||||
*
|
||||
* \return true for success, false for failure.
|
||||
*/
|
||||
bool SdBaseFile::openParent(SdBaseFile* dir) {
|
||||
bool SdBaseFile::openParent(SdBaseFile *dir) {
|
||||
dir_t entry;
|
||||
dir_t* p;
|
||||
SdBaseFile file;
|
||||
uint32_t c;
|
||||
uint32_t cluster;
|
||||
@@ -835,7 +840,7 @@ bool SdBaseFile::openParent(SdBaseFile* dir) {
|
||||
// first block of parent dir
|
||||
if (!vol_->cacheRawBlock(lbn, SdVolume::CACHE_FOR_READ)) return false;
|
||||
|
||||
p = &vol_->cacheBuffer_.dir[1];
|
||||
dir_t *p = &vol_->cacheBuffer_.dir[1];
|
||||
// verify name for '../..'
|
||||
if (p->name[0] != '.' || p->name[1] != '.') return false;
|
||||
// '..' is pointer to first cluster of parent. open '../..' to find parent
|
||||
@@ -866,7 +871,7 @@ bool SdBaseFile::openParent(SdBaseFile* dir) {
|
||||
* Reasons for failure include the file is already open, the FAT volume has
|
||||
* not been initialized or it a FAT12 volume.
|
||||
*/
|
||||
bool SdBaseFile::openRoot(SdVolume* vol) {
|
||||
bool SdBaseFile::openRoot(SdVolume *vol) {
|
||||
// error if file is already open
|
||||
if (isOpen()) return false;
|
||||
|
||||
@@ -911,7 +916,7 @@ int SdBaseFile::peek() {
|
||||
// print uint8_t with width 2
|
||||
static void print2u(const uint8_t v) {
|
||||
if (v < 10) SERIAL_CHAR('0');
|
||||
SERIAL_ECHO(int(v));
|
||||
SERIAL_ECHO(v);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -993,8 +998,8 @@ int16_t SdBaseFile::read() {
|
||||
* read() called before a file has been opened, corrupt file system
|
||||
* or an I/O error occurred.
|
||||
*/
|
||||
int16_t SdBaseFile::read(void* buf, uint16_t nbyte) {
|
||||
uint8_t* dst = reinterpret_cast<uint8_t*>(buf);
|
||||
int16_t SdBaseFile::read(void *buf, uint16_t nbyte) {
|
||||
uint8_t *dst = reinterpret_cast<uint8_t*>(buf);
|
||||
uint16_t offset, toRead;
|
||||
uint32_t block; // raw device block number
|
||||
|
||||
@@ -1034,7 +1039,7 @@ int16_t SdBaseFile::read(void* buf, uint16_t nbyte) {
|
||||
else {
|
||||
// read block to cache and copy data to caller
|
||||
if (!vol_->cacheRawBlock(block, SdVolume::CACHE_FOR_READ)) return -1;
|
||||
uint8_t* src = vol_->cache()->data + offset;
|
||||
uint8_t *src = vol_->cache()->data + offset;
|
||||
memcpy(dst, src, n);
|
||||
}
|
||||
dst += n;
|
||||
@@ -1044,6 +1049,20 @@ int16_t SdBaseFile::read(void* buf, uint16_t nbyte) {
|
||||
return nbyte;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate a checksum for an 8.3 filename
|
||||
*
|
||||
* \param name The 8.3 file name to calculate
|
||||
*
|
||||
* \return The checksum byte
|
||||
*/
|
||||
uint8_t lfn_checksum(const uint8_t *name) {
|
||||
uint8_t sum = 0;
|
||||
for (uint8_t i = 11; i; i--)
|
||||
sum = ((sum & 1) << 7) + (sum >> 1) + *name++;
|
||||
return sum;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read the next entry in a directory.
|
||||
*
|
||||
@@ -1055,52 +1074,116 @@ int16_t SdBaseFile::read(void* buf, uint16_t nbyte) {
|
||||
* readDir() called before a directory has been opened, this is not
|
||||
* a directory file or an I/O error occurred.
|
||||
*/
|
||||
int8_t SdBaseFile::readDir(dir_t* dir, char* longFilename) {
|
||||
int8_t SdBaseFile::readDir(dir_t *dir, char *longFilename) {
|
||||
int16_t n;
|
||||
// if not a directory file or miss-positioned return an error
|
||||
if (!isDir() || (0x1F & curPosition_)) return -1;
|
||||
|
||||
#define INVALIDATE_LONGNAME() (longFilename[0] = longFilename[1] = '\0')
|
||||
|
||||
// If we have a longFilename buffer, mark it as invalid.
|
||||
// If a long filename is found it will be filled automatically.
|
||||
if (longFilename) longFilename[0] = '\0';
|
||||
if (longFilename) INVALIDATE_LONGNAME();
|
||||
|
||||
uint8_t checksum_error = 0xFF, checksum = 0;
|
||||
|
||||
while (1) {
|
||||
|
||||
n = read(dir, sizeof(dir_t));
|
||||
if (n != sizeof(dir_t)) return n ? -1 : 0;
|
||||
|
||||
// last entry if DIR_NAME_FREE
|
||||
// Last entry if DIR_NAME_FREE
|
||||
if (dir->name[0] == DIR_NAME_FREE) return 0;
|
||||
|
||||
// skip deleted entry and entry for . and ..
|
||||
// Skip deleted entry and entry for . and ..
|
||||
if (dir->name[0] == DIR_NAME_DELETED || dir->name[0] == '.') {
|
||||
if (longFilename) longFilename[0] = '\0'; // Invalidate erased file long name, if any
|
||||
if (longFilename) INVALIDATE_LONGNAME(); // Invalidate erased file long name, if any
|
||||
continue;
|
||||
}
|
||||
|
||||
// Fill the long filename if we have a long filename entry.
|
||||
// Long filename entries are stored before the short filename.
|
||||
if (longFilename && DIR_IS_LONG_NAME(dir)) {
|
||||
vfat_t* VFAT = (vfat_t*)dir;
|
||||
// Sanity-check the VFAT entry. The first cluster is always set to zero. And the sequence number should be higher than 0
|
||||
if (VFAT->firstClusterLow == 0) {
|
||||
const uint8_t seq = VFAT->sequenceNumber & 0x1F;
|
||||
if (WITHIN(seq, 1, MAX_VFAT_ENTRIES)) {
|
||||
// TODO: Store the filename checksum to verify if a long-filename-unaware system modified the file table.
|
||||
n = (seq - 1) * (FILENAME_LENGTH);
|
||||
LOOP_L_N(i, FILENAME_LENGTH)
|
||||
longFilename[n + i] = (i < 5) ? VFAT->name1[i] : (i < 11) ? VFAT->name2[i - 5] : VFAT->name3[i - 11];
|
||||
// If this VFAT entry is the last one, add a NUL terminator at the end of the string
|
||||
if (VFAT->sequenceNumber & 0x40) longFilename[n + FILENAME_LENGTH] = '\0';
|
||||
if (longFilename) {
|
||||
// Fill the long filename if we have a long filename entry.
|
||||
// Long filename entries are stored before the short filename.
|
||||
if (DIR_IS_LONG_NAME(dir)) {
|
||||
vfat_t *VFAT = (vfat_t*)dir;
|
||||
// Sanity-check the VFAT entry. The first cluster is always set to zero. And the sequence number should be higher than 0
|
||||
if (VFAT->firstClusterLow == 0) {
|
||||
const uint8_t seq = VFAT->sequenceNumber & 0x1F;
|
||||
if (WITHIN(seq, 1, MAX_VFAT_ENTRIES)) {
|
||||
n = (seq - 1) * (FILENAME_LENGTH);
|
||||
if (n == 0) {
|
||||
checksum = VFAT->checksum;
|
||||
checksum_error = 0;
|
||||
}
|
||||
else if (checksum != VFAT->checksum) // orphan detected
|
||||
checksum_error = 1;
|
||||
|
||||
LOOP_L_N(i, FILENAME_LENGTH) {
|
||||
const uint16_t utf16_ch = (i >= 11) ? VFAT->name3[i - 11] : (i >= 5) ? VFAT->name2[i - 5] : VFAT->name1[i];
|
||||
#if ENABLED(UTF_FILENAME_SUPPORT)
|
||||
// We can't reconvert to UTF-8 here as UTF-8 is variable-size encoding, but joining LFN blocks
|
||||
// needs static bytes addressing. So here just store full UTF-16LE words to re-convert later.
|
||||
uint16_t idx = (n + i) * 2; // This is fixed as FAT LFN always contain UTF-16LE encoding
|
||||
longFilename[idx] = utf16_ch & 0xFF;
|
||||
longFilename[idx + 1] = (utf16_ch >> 8) & 0xFF;
|
||||
#else
|
||||
// Replace all multibyte characters to '_'
|
||||
longFilename[n + i] = (utf16_ch > 0xFF) ? '_' : (utf16_ch & 0xFF);
|
||||
#endif
|
||||
}
|
||||
// If this VFAT entry is the last one, add a NUL terminator at the end of the string
|
||||
if (VFAT->sequenceNumber & 0x40)
|
||||
longFilename[(n + FILENAME_LENGTH) * LONG_FILENAME_CHARSIZE] = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!checksum_error && lfn_checksum(dir->name) != checksum) checksum_error = 1; // orphan detected
|
||||
if (checksum_error) INVALIDATE_LONGNAME();
|
||||
}
|
||||
}
|
||||
// Return if normal file or subdirectory
|
||||
if (DIR_IS_FILE_OR_SUBDIR(dir)) return n;
|
||||
|
||||
// Post-process normal file or subdirectory longname, if any
|
||||
if (DIR_IS_FILE_OR_SUBDIR(dir)) {
|
||||
#if ENABLED(UTF_FILENAME_SUPPORT)
|
||||
#if LONG_FILENAME_CHARSIZE > 2
|
||||
// Add warning for developers for currently not supported 3-byte cases (Conversion series of 2-byte
|
||||
// codepoints to 3-byte in-place will break the rest of filename)
|
||||
#error "Currently filename re-encoding is done in-place. It may break the remaining chars to use 3-byte codepoints."
|
||||
#endif
|
||||
|
||||
// Is there a long filename to decode?
|
||||
if (longFilename) {
|
||||
// Reset n to the start of the long name
|
||||
n = 0;
|
||||
for (uint16_t idx = 0; idx < (LONG_FILENAME_LENGTH) / 2; idx += 2) { // idx is fixed since FAT LFN always contains UTF-16LE encoding
|
||||
const uint16_t utf16_ch = longFilename[idx] | (longFilename[idx + 1] << 8);
|
||||
if (0xD800 == (utf16_ch & 0xF800)) // Surrogate pair - encode as '_'
|
||||
longFilename[n++] = '_';
|
||||
else if (0 == (utf16_ch & 0xFF80)) // Encode as 1-byte UTF-8 char
|
||||
longFilename[n++] = utf16_ch & 0x007F;
|
||||
else if (0 == (utf16_ch & 0xF800)) { // Encode as 2-byte UTF-8 char
|
||||
longFilename[n++] = 0xC0 | ((utf16_ch >> 6) & 0x1F);
|
||||
longFilename[n++] = 0x80 | ( utf16_ch & 0x3F);
|
||||
}
|
||||
else {
|
||||
#if LONG_FILENAME_CHARSIZE > 2 // Encode as 3-byte UTF-8 char
|
||||
longFilename[n++] = 0xE0 | ((utf16_ch >> 12) & 0x0F);
|
||||
longFilename[n++] = 0xC0 | ((utf16_ch >> 6) & 0x3F);
|
||||
longFilename[n++] = 0xC0 | ( utf16_ch & 0x3F);
|
||||
#else // Encode as '_'
|
||||
longFilename[n++] = '_';
|
||||
#endif
|
||||
}
|
||||
if (0 == utf16_ch) break; // End of filename
|
||||
} // idx
|
||||
} // longFilename
|
||||
#endif
|
||||
return n;
|
||||
} // DIR_IS_FILE_OR_SUBDIR
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Read next directory entry into the cache
|
||||
// Assumes file is correctly positioned
|
||||
dir_t* SdBaseFile::readDirCache() {
|
||||
@@ -1135,12 +1218,13 @@ dir_t* SdBaseFile::readDirCache() {
|
||||
* or an I/O error occurred.
|
||||
*/
|
||||
bool SdBaseFile::remove() {
|
||||
dir_t* d;
|
||||
if (ENABLED(SDCARD_READONLY)) return false;
|
||||
|
||||
// free any clusters - will fail if read-only or directory
|
||||
if (!truncate(0)) return false;
|
||||
|
||||
// cache directory entry
|
||||
d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE);
|
||||
dir_t *d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE);
|
||||
if (!d) return false;
|
||||
|
||||
// mark entry deleted
|
||||
@@ -1171,7 +1255,9 @@ bool SdBaseFile::remove() {
|
||||
* \a dirFile is not a directory, \a path is not found
|
||||
* or an I/O error occurred.
|
||||
*/
|
||||
bool SdBaseFile::remove(SdBaseFile* dirFile, const char* path) {
|
||||
bool SdBaseFile::remove(SdBaseFile *dirFile, const char *path) {
|
||||
if (ENABLED(SDCARD_READONLY)) return false;
|
||||
|
||||
SdBaseFile file;
|
||||
return file.open(dirFile, path, O_WRITE) ? file.remove() : false;
|
||||
}
|
||||
@@ -1186,11 +1272,10 @@ bool SdBaseFile::remove(SdBaseFile* dirFile, const char* path) {
|
||||
* Reasons for failure include \a dirFile is not open or is not a directory
|
||||
* file, newPath is invalid or already exists, or an I/O error occurs.
|
||||
*/
|
||||
bool SdBaseFile::rename(SdBaseFile* dirFile, const char* newPath) {
|
||||
dir_t entry;
|
||||
bool SdBaseFile::rename(SdBaseFile *dirFile, const char *newPath) {
|
||||
if (ENABLED(SDCARD_READONLY)) return false;
|
||||
|
||||
uint32_t dirCluster = 0;
|
||||
SdBaseFile file;
|
||||
dir_t* d;
|
||||
|
||||
// must be an open file or subdirectory
|
||||
if (!(isFile() || isSubDir())) return false;
|
||||
@@ -1200,16 +1285,18 @@ bool SdBaseFile::rename(SdBaseFile* dirFile, const char* newPath) {
|
||||
|
||||
// sync() and cache directory entry
|
||||
sync();
|
||||
d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE);
|
||||
dir_t *d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE);
|
||||
if (!d) return false;
|
||||
|
||||
// save directory entry
|
||||
dir_t entry;
|
||||
memcpy(&entry, d, sizeof(entry));
|
||||
|
||||
// mark entry deleted
|
||||
d->name[0] = DIR_NAME_DELETED;
|
||||
|
||||
// make directory entry for new path
|
||||
SdBaseFile file;
|
||||
if (isFile()) {
|
||||
if (!file.open(dirFile, newPath, O_CREAT | O_EXCL | O_WRITE)) {
|
||||
goto restore;
|
||||
@@ -1279,6 +1366,8 @@ restore:
|
||||
* directory, is not empty, or an I/O error occurred.
|
||||
*/
|
||||
bool SdBaseFile::rmdir() {
|
||||
if (ENABLED(SDCARD_READONLY)) return false;
|
||||
|
||||
// must be open subdirectory
|
||||
if (!isSubDir()) return false;
|
||||
|
||||
@@ -1286,7 +1375,7 @@ bool SdBaseFile::rmdir() {
|
||||
|
||||
// make sure directory is empty
|
||||
while (curPosition_ < fileSize_) {
|
||||
dir_t* p = readDirCache();
|
||||
dir_t *p = readDirCache();
|
||||
if (!p) return false;
|
||||
// done if past last used entry
|
||||
if (p->name[0] == DIR_NAME_FREE) break;
|
||||
@@ -1317,6 +1406,8 @@ bool SdBaseFile::rmdir() {
|
||||
* \return true for success, false for failure.
|
||||
*/
|
||||
bool SdBaseFile::rmRfStar() {
|
||||
if (ENABLED(SDCARD_READONLY)) return false;
|
||||
|
||||
uint32_t index;
|
||||
SdBaseFile f;
|
||||
rewind();
|
||||
@@ -1324,7 +1415,7 @@ bool SdBaseFile::rmRfStar() {
|
||||
// remember position
|
||||
index = curPosition_ / 32;
|
||||
|
||||
dir_t* p = readDirCache();
|
||||
dir_t *p = readDirCache();
|
||||
if (!p) return false;
|
||||
|
||||
// done if past last entry
|
||||
@@ -1366,7 +1457,7 @@ bool SdBaseFile::rmRfStar() {
|
||||
* \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive
|
||||
* OR of open flags. see SdBaseFile::open(SdBaseFile*, const char*, uint8_t).
|
||||
*/
|
||||
SdBaseFile::SdBaseFile(const char* path, uint8_t oflag) {
|
||||
SdBaseFile::SdBaseFile(const char *path, uint8_t oflag) {
|
||||
type_ = FAT_FILE_TYPE_CLOSED;
|
||||
writeError = false;
|
||||
open(path, oflag);
|
||||
@@ -1409,7 +1500,7 @@ bool SdBaseFile::seekSet(const uint32_t pos) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void SdBaseFile::setpos(filepos_t* pos) {
|
||||
void SdBaseFile::setpos(filepos_t *pos) {
|
||||
curPosition_ = pos->position;
|
||||
curCluster_ = pos->cluster;
|
||||
}
|
||||
@@ -1424,10 +1515,10 @@ void SdBaseFile::setpos(filepos_t* pos) {
|
||||
*/
|
||||
bool SdBaseFile::sync() {
|
||||
// only allow open files and directories
|
||||
if (!isOpen()) goto FAIL;
|
||||
if (ENABLED(SDCARD_READONLY) || !isOpen()) goto FAIL;
|
||||
|
||||
if (flags_ & F_FILE_DIR_DIRTY) {
|
||||
dir_t* d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE);
|
||||
dir_t *d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE);
|
||||
// check for deleted by another open file object
|
||||
if (!d || d->name[0] == DIR_NAME_DELETED) goto FAIL;
|
||||
|
||||
@@ -1464,8 +1555,7 @@ bool SdBaseFile::sync() {
|
||||
*
|
||||
* \return true for success, false for failure.
|
||||
*/
|
||||
bool SdBaseFile::timestamp(SdBaseFile* file) {
|
||||
dir_t* d;
|
||||
bool SdBaseFile::timestamp(SdBaseFile *file) {
|
||||
dir_t dir;
|
||||
|
||||
// get timestamps
|
||||
@@ -1474,7 +1564,7 @@ bool SdBaseFile::timestamp(SdBaseFile* file) {
|
||||
// update directory fields
|
||||
if (!sync()) return false;
|
||||
|
||||
d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE);
|
||||
dir_t *d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE);
|
||||
if (!d) return false;
|
||||
|
||||
// copy timestamps
|
||||
@@ -1524,8 +1614,9 @@ bool SdBaseFile::timestamp(SdBaseFile* file) {
|
||||
*/
|
||||
bool SdBaseFile::timestamp(uint8_t flags, uint16_t year, uint8_t month,
|
||||
uint8_t day, uint8_t hour, uint8_t minute, uint8_t second) {
|
||||
if (ENABLED(SDCARD_READONLY)) return false;
|
||||
|
||||
uint16_t dirDate, dirTime;
|
||||
dir_t* d;
|
||||
|
||||
if (!isOpen()
|
||||
|| year < 1980
|
||||
@@ -1542,7 +1633,7 @@ bool SdBaseFile::timestamp(uint8_t flags, uint16_t year, uint8_t month,
|
||||
// update directory entry
|
||||
if (!sync()) return false;
|
||||
|
||||
d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE);
|
||||
dir_t *d = cacheDirEntry(SdVolume::CACHE_FOR_WRITE);
|
||||
if (!d) return false;
|
||||
|
||||
dirDate = FAT_DATE(year, month, day);
|
||||
@@ -1575,6 +1666,8 @@ bool SdBaseFile::timestamp(uint8_t flags, uint16_t year, uint8_t month,
|
||||
* \a length is greater than the current file size or an I/O error occurs.
|
||||
*/
|
||||
bool SdBaseFile::truncate(uint32_t length) {
|
||||
if (ENABLED(SDCARD_READONLY)) return false;
|
||||
|
||||
uint32_t newPos;
|
||||
// error if not a normal file or read-only
|
||||
if (!isFile() || !(flags_ & O_WRITE)) return false;
|
||||
@@ -1633,11 +1726,14 @@ bool SdBaseFile::truncate(uint32_t length) {
|
||||
* \a nbyte. If an error occurs, write() returns -1. Possible errors
|
||||
* include write() is called before a file has been opened, write is called
|
||||
* for a read-only file, device is full, a corrupt file system or an I/O error.
|
||||
*
|
||||
*/
|
||||
int16_t SdBaseFile::write(const void* buf, uint16_t nbyte) {
|
||||
int16_t SdBaseFile::write(const void *buf, uint16_t nbyte) {
|
||||
#if ENABLED(SDCARD_READONLY)
|
||||
writeError = true; return -1;
|
||||
#endif
|
||||
|
||||
// convert void* to uint8_t* - must be before goto statements
|
||||
const uint8_t* src = reinterpret_cast<const uint8_t*>(buf);
|
||||
const uint8_t *src = reinterpret_cast<const uint8_t*>(buf);
|
||||
|
||||
// number of bytes left to write - must be before goto statements
|
||||
uint16_t nToWrite = nbyte;
|
||||
@@ -1703,7 +1799,7 @@ int16_t SdBaseFile::write(const void* buf, uint16_t nbyte) {
|
||||
// rewrite part of block
|
||||
if (!vol_->cacheRawBlock(block, SdVolume::CACHE_FOR_WRITE)) goto FAIL;
|
||||
}
|
||||
uint8_t* dst = vol_->cache()->data + blockOffset;
|
||||
uint8_t *dst = vol_->cache()->data + blockOffset;
|
||||
memcpy(dst, src, n);
|
||||
}
|
||||
curPosition_ += n;
|
||||
|
73
Marlin/src/sd/SdBaseFile.h
Executable file → Normal file
73
Marlin/src/sd/SdBaseFile.h
Executable file → Normal file
@@ -16,17 +16,14 @@
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \brief SdBaseFile class
|
||||
*/
|
||||
|
||||
/**
|
||||
* sd/SdBaseFile.h
|
||||
*
|
||||
* Arduino SdFat Library
|
||||
* Copyright (c) 2009 by William Greiman
|
||||
*
|
||||
@@ -166,7 +163,7 @@ uint16_t const FAT_DEFAULT_TIME = (1 << 11);
|
||||
class SdBaseFile {
|
||||
public:
|
||||
SdBaseFile() : writeError(false), type_(FAT_FILE_TYPE_CLOSED) {}
|
||||
SdBaseFile(const char* path, uint8_t oflag);
|
||||
SdBaseFile(const char *path, uint8_t oflag);
|
||||
~SdBaseFile() { if (isOpen()) close(); }
|
||||
|
||||
/**
|
||||
@@ -182,18 +179,18 @@ class SdBaseFile {
|
||||
* get position for streams
|
||||
* \param[out] pos struct to receive position
|
||||
*/
|
||||
void getpos(filepos_t* pos);
|
||||
void getpos(filepos_t *pos);
|
||||
|
||||
/**
|
||||
* set position for streams
|
||||
* \param[out] pos struct with value for new position
|
||||
*/
|
||||
void setpos(filepos_t* pos);
|
||||
void setpos(filepos_t *pos);
|
||||
|
||||
bool close();
|
||||
bool contiguousRange(uint32_t* bgnBlock, uint32_t* endBlock);
|
||||
bool createContiguous(SdBaseFile* dirFile,
|
||||
const char* path, uint32_t size);
|
||||
bool contiguousRange(uint32_t *bgnBlock, uint32_t *endBlock);
|
||||
bool createContiguous(SdBaseFile *dirFile,
|
||||
const char *path, uint32_t size);
|
||||
/**
|
||||
* \return The current cluster number for a file or directory.
|
||||
*/
|
||||
@@ -207,7 +204,7 @@ class SdBaseFile {
|
||||
/**
|
||||
* \return Current working directory
|
||||
*/
|
||||
static SdBaseFile* cwd() { return cwd_; }
|
||||
static SdBaseFile *cwd() { return cwd_; }
|
||||
|
||||
/**
|
||||
* Set the date/time callback function
|
||||
@@ -216,7 +213,7 @@ class SdBaseFile {
|
||||
* function is of the form:
|
||||
*
|
||||
* \code
|
||||
* void dateTime(uint16_t* date, uint16_t* time) {
|
||||
* void dateTime(uint16_t *date, uint16_t *time) {
|
||||
* uint16_t year;
|
||||
* uint8_t month, day, hour, minute, second;
|
||||
*
|
||||
@@ -238,7 +235,7 @@ class SdBaseFile {
|
||||
* See the timestamp() function.
|
||||
*/
|
||||
static void dateTimeCallback(
|
||||
void (*dateTime)(uint16_t* date, uint16_t* time)) {
|
||||
void (*dateTime)(uint16_t *date, uint16_t *time)) {
|
||||
dateTime_ = dateTime;
|
||||
}
|
||||
|
||||
@@ -246,10 +243,10 @@ class SdBaseFile {
|
||||
* Cancel the date/time callback function.
|
||||
*/
|
||||
static void dateTimeCallbackCancel() { dateTime_ = 0; }
|
||||
bool dirEntry(dir_t* dir);
|
||||
static void dirName(const dir_t& dir, char* name);
|
||||
bool exists(const char* name);
|
||||
int16_t fgets(char* str, int16_t num, char* delim = 0);
|
||||
bool dirEntry(dir_t *dir);
|
||||
static void dirName(const dir_t& dir, char *name);
|
||||
bool exists(const char *name);
|
||||
int16_t fgets(char *str, int16_t num, char *delim = 0);
|
||||
|
||||
/**
|
||||
* \return The total number of bytes in a file or directory.
|
||||
@@ -289,27 +286,27 @@ class SdBaseFile {
|
||||
bool getDosName(char * const name);
|
||||
void ls(uint8_t flags = 0, uint8_t indent = 0);
|
||||
|
||||
bool mkdir(SdBaseFile* dir, const char* path, bool pFlag = true);
|
||||
bool open(SdBaseFile* dirFile, uint16_t index, uint8_t oflag);
|
||||
bool open(SdBaseFile* dirFile, const char* path, uint8_t oflag);
|
||||
bool open(const char* path, uint8_t oflag = O_READ);
|
||||
bool openNext(SdBaseFile* dirFile, uint8_t oflag);
|
||||
bool openRoot(SdVolume* vol);
|
||||
bool mkdir(SdBaseFile *dir, const char *path, bool pFlag = true);
|
||||
bool open(SdBaseFile *dirFile, uint16_t index, uint8_t oflag);
|
||||
bool open(SdBaseFile *dirFile, const char *path, uint8_t oflag);
|
||||
bool open(const char *path, uint8_t oflag = O_READ);
|
||||
bool openNext(SdBaseFile *dirFile, uint8_t oflag);
|
||||
bool openRoot(SdVolume *vol);
|
||||
int peek();
|
||||
static void printFatDate(uint16_t fatDate);
|
||||
static void printFatTime(uint16_t fatTime);
|
||||
bool printName();
|
||||
int16_t read();
|
||||
int16_t read(void* buf, uint16_t nbyte);
|
||||
int8_t readDir(dir_t* dir, char* longFilename);
|
||||
static bool remove(SdBaseFile* dirFile, const char* path);
|
||||
int16_t read(void *buf, uint16_t nbyte);
|
||||
int8_t readDir(dir_t *dir, char *longFilename);
|
||||
static bool remove(SdBaseFile *dirFile, const char *path);
|
||||
bool remove();
|
||||
|
||||
/**
|
||||
* Set the file's current position to zero.
|
||||
*/
|
||||
void rewind() { seekSet(0); }
|
||||
bool rename(SdBaseFile* dirFile, const char* newPath);
|
||||
bool rename(SdBaseFile *dirFile, const char *newPath);
|
||||
bool rmdir();
|
||||
bool rmRfStar();
|
||||
|
||||
@@ -328,7 +325,7 @@ class SdBaseFile {
|
||||
bool seekEnd(const int32_t offset = 0) { return seekSet(fileSize_ + offset); }
|
||||
bool seekSet(const uint32_t pos);
|
||||
bool sync();
|
||||
bool timestamp(SdBaseFile* file);
|
||||
bool timestamp(SdBaseFile *file);
|
||||
bool timestamp(uint8_t flag, uint16_t year, uint8_t month, uint8_t day,
|
||||
uint8_t hour, uint8_t minute, uint8_t second);
|
||||
|
||||
@@ -344,14 +341,14 @@ class SdBaseFile {
|
||||
* \return SdVolume that contains this file.
|
||||
*/
|
||||
SdVolume* volume() const { return vol_; }
|
||||
int16_t write(const void* buf, uint16_t nbyte);
|
||||
int16_t write(const void *buf, uint16_t nbyte);
|
||||
|
||||
private:
|
||||
friend class SdFat; // allow SdFat to set cwd_
|
||||
static SdBaseFile* cwd_; // global pointer to cwd dir
|
||||
static SdBaseFile *cwd_; // global pointer to cwd dir
|
||||
|
||||
// data time callback function
|
||||
static void (*dateTime_)(uint16_t* date, uint16_t* time);
|
||||
static void (*dateTime_)(uint16_t *date, uint16_t *time);
|
||||
|
||||
// bits defined in flags_
|
||||
static uint8_t const F_OFLAG = (O_ACCMODE | O_APPEND | O_SYNC), // should be 0x0F
|
||||
@@ -367,21 +364,21 @@ class SdBaseFile {
|
||||
uint8_t dirIndex_; // index of directory entry in dirBlock
|
||||
uint32_t fileSize_; // file size in bytes
|
||||
uint32_t firstCluster_; // first cluster of file
|
||||
SdVolume* vol_; // volume where file is located
|
||||
SdVolume *vol_; // volume where file is located
|
||||
|
||||
/**
|
||||
* EXPERIMENTAL - Don't use!
|
||||
*/
|
||||
//bool openParent(SdBaseFile* dir);
|
||||
//bool openParent(SdBaseFile *dir);
|
||||
|
||||
// private functions
|
||||
bool addCluster();
|
||||
bool addDirCluster();
|
||||
dir_t* cacheDirEntry(uint8_t action);
|
||||
int8_t lsPrintNext(uint8_t flags, uint8_t indent);
|
||||
static bool make83Name(const char* str, uint8_t* name, const char** ptr);
|
||||
bool mkdir(SdBaseFile* parent, const uint8_t dname[11]);
|
||||
bool open(SdBaseFile* dirFile, const uint8_t dname[11], uint8_t oflag);
|
||||
static bool make83Name(const char *str, uint8_t *name, const char **ptr);
|
||||
bool mkdir(SdBaseFile *parent, const uint8_t dname[11]);
|
||||
bool open(SdBaseFile *dirFile, const uint8_t dname[11], uint8_t oflag);
|
||||
bool openCachedEntry(uint8_t cacheIndex, uint8_t oflags);
|
||||
dir_t* readDirCache();
|
||||
};
|
||||
|
14
Marlin/src/sd/SdFatConfig.h
Executable file → Normal file
14
Marlin/src/sd/SdFatConfig.h
Executable file → Normal file
@@ -16,13 +16,14 @@
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* SdFatConfig.h
|
||||
* sd/SdFatConfig.h
|
||||
*
|
||||
* Arduino SdFat Library
|
||||
* Copyright (c) 2009 by William Greiman
|
||||
*
|
||||
@@ -38,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
|
||||
@@ -102,5 +103,10 @@
|
||||
|
||||
#define FILENAME_LENGTH 13 // Number of UTF-16 characters per entry
|
||||
|
||||
// UTF-8 may use up to 3 bytes to represent single UTF-16 code point.
|
||||
// We discard 3-byte characters allowing only 2-bytes
|
||||
// or 1-byte if UTF_FILENAME_SUPPORT disabled.
|
||||
#define LONG_FILENAME_CHARSIZE TERN(UTF_FILENAME_SUPPORT, 2, 1)
|
||||
|
||||
// Total bytes needed to store a single long filename
|
||||
#define LONG_FILENAME_LENGTH (FILENAME_LENGTH * MAX_VFAT_ENTRIES + 1)
|
||||
#define LONG_FILENAME_LENGTH (FILENAME_LENGTH * LONG_FILENAME_CHARSIZE * MAX_VFAT_ENTRIES + 1)
|
||||
|
21
Marlin/src/sd/SdFatStructs.h
Executable file → Normal file
21
Marlin/src/sd/SdFatStructs.h
Executable file → Normal file
@@ -16,17 +16,14 @@
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \brief FAT file structures
|
||||
*/
|
||||
|
||||
/**
|
||||
* sd/SdFatStructs.h
|
||||
*
|
||||
* Arduino SdFat Library
|
||||
* Copyright (c) 2009 by William Greiman
|
||||
*
|
||||
@@ -39,7 +36,7 @@
|
||||
|
||||
/**
|
||||
* mostly from Microsoft document fatgen103.doc
|
||||
* http://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx
|
||||
* https://www.microsoft.com/whdc/system/platform/firmware/fatgen.mspx
|
||||
*/
|
||||
|
||||
uint8_t const BOOTSIG0 = 0x55, // Value for byte 510 of boot block or MBR
|
||||
@@ -128,7 +125,6 @@ typedef struct masterBootRecord mbr_t;
|
||||
* \struct fat_boot
|
||||
*
|
||||
* \brief Boot sector for a FAT12/FAT16 volume.
|
||||
*
|
||||
*/
|
||||
struct fat_boot {
|
||||
/**
|
||||
@@ -409,7 +405,6 @@ uint32_t const FSINFO_LEAD_SIG = 0x41615252, // 'AaRR' Lead signature for a F
|
||||
* \struct fat32_fsinfo
|
||||
*
|
||||
* \brief FSINFO sector for a FAT32 volume.
|
||||
*
|
||||
*/
|
||||
struct fat32_fsinfo {
|
||||
uint32_t leadSignature; // must be 0x52, 0x52, 0x61, 0x41 'RRaA'
|
||||
@@ -576,7 +571,7 @@ uint8_t const DIR_NAME_0xE5 = 0x05, // escape for name[0] = 0xE5
|
||||
*
|
||||
* \return true if the entry is for part of a long name else false.
|
||||
*/
|
||||
static inline uint8_t DIR_IS_LONG_NAME(const dir_t* dir) {
|
||||
static inline uint8_t DIR_IS_LONG_NAME(const dir_t *dir) {
|
||||
return (dir->attributes & DIR_ATT_LONG_NAME_MASK) == DIR_ATT_LONG_NAME;
|
||||
}
|
||||
|
||||
@@ -589,7 +584,7 @@ uint8_t const DIR_ATT_FILE_TYPE_MASK = (DIR_ATT_VOLUME_ID | DIR_ATT_DIRECTORY);
|
||||
*
|
||||
* \return true if the entry is for a normal file else false.
|
||||
*/
|
||||
static inline uint8_t DIR_IS_FILE(const dir_t* dir) {
|
||||
static inline uint8_t DIR_IS_FILE(const dir_t *dir) {
|
||||
return (dir->attributes & DIR_ATT_FILE_TYPE_MASK) == 0;
|
||||
}
|
||||
|
||||
@@ -599,7 +594,7 @@ static inline uint8_t DIR_IS_FILE(const dir_t* dir) {
|
||||
*
|
||||
* \return true if the entry is for a subdirectory else false.
|
||||
*/
|
||||
static inline uint8_t DIR_IS_SUBDIR(const dir_t* dir) {
|
||||
static inline uint8_t DIR_IS_SUBDIR(const dir_t *dir) {
|
||||
return (dir->attributes & DIR_ATT_FILE_TYPE_MASK) == DIR_ATT_DIRECTORY;
|
||||
}
|
||||
|
||||
@@ -609,6 +604,6 @@ static inline uint8_t DIR_IS_SUBDIR(const dir_t* dir) {
|
||||
*
|
||||
* \return true if the entry is for a normal file or subdirectory else false.
|
||||
*/
|
||||
static inline uint8_t DIR_IS_FILE_OR_SUBDIR(const dir_t* dir) {
|
||||
static inline uint8_t DIR_IS_FILE_OR_SUBDIR(const dir_t *dir) {
|
||||
return (dir->attributes & DIR_ATT_VOLUME_ID) == 0;
|
||||
}
|
||||
|
6
Marlin/src/sd/SdFatUtil.cpp
Executable file → Normal file
6
Marlin/src/sd/SdFatUtil.cpp
Executable file → Normal file
@@ -16,11 +16,13 @@
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* sd/SdFatUtil.cpp
|
||||
*
|
||||
* Arduino SdFat Library
|
||||
* Copyright (c) 2008 by William Greiman
|
||||
*
|
||||
@@ -46,7 +48,7 @@
|
||||
return &top - reinterpret_cast<char*>(sbrk(0));
|
||||
}
|
||||
|
||||
#else
|
||||
#elif defined(__AVR__)
|
||||
|
||||
extern char* __brkval;
|
||||
extern char __bss_end;
|
||||
|
4
Marlin/src/sd/SdFatUtil.h
Executable file → Normal file
4
Marlin/src/sd/SdFatUtil.h
Executable file → Normal file
@@ -16,12 +16,14 @@
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* sd/SdFatUtil.h
|
||||
*
|
||||
* Arduino SdFat Library
|
||||
* Copyright (c) 2008 by William Greiman
|
||||
*
|
||||
|
11
Marlin/src/sd/SdFile.cpp
Executable file → Normal file
11
Marlin/src/sd/SdFile.cpp
Executable file → Normal file
@@ -16,11 +16,13 @@
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* sd/SdFile.cpp
|
||||
*
|
||||
* Arduino SdFat Library
|
||||
* Copyright (c) 2009 by William Greiman
|
||||
*
|
||||
@@ -41,7 +43,7 @@
|
||||
* \param[in] oflag Values for \a oflag are constructed by a bitwise-inclusive
|
||||
* OR of open flags. see SdBaseFile::open(SdBaseFile*, const char*, uint8_t).
|
||||
*/
|
||||
SdFile::SdFile(const char* path, uint8_t oflag) : SdBaseFile(path, oflag) { }
|
||||
SdFile::SdFile(const char *path, uint8_t oflag) : SdBaseFile(path, oflag) { }
|
||||
|
||||
/**
|
||||
* Write data to an open file.
|
||||
@@ -57,9 +59,8 @@ SdFile::SdFile(const char* path, uint8_t oflag) : SdBaseFile(path, oflag) { }
|
||||
* \a nbyte. If an error occurs, write() returns -1. Possible errors
|
||||
* include write() is called before a file has been opened, write is called
|
||||
* for a read-only file, device is full, a corrupt file system or an I/O error.
|
||||
*
|
||||
*/
|
||||
int16_t SdFile::write(const void* buf, uint16_t nbyte) { return SdBaseFile::write(buf, nbyte); }
|
||||
int16_t SdFile::write(const void *buf, uint16_t nbyte) { return SdBaseFile::write(buf, nbyte); }
|
||||
|
||||
/**
|
||||
* Write a byte to a file. Required by the Arduino Print class.
|
||||
@@ -77,7 +78,7 @@ int16_t SdFile::write(const void* buf, uint16_t nbyte) { return SdBaseFile::writ
|
||||
* \param[in] str Pointer to the string.
|
||||
* Use writeError to check for errors.
|
||||
*/
|
||||
void SdFile::write(const char* str) { SdBaseFile::write(str, strlen(str)); }
|
||||
void SdFile::write(const char *str) { SdBaseFile::write(str, strlen(str)); }
|
||||
|
||||
/**
|
||||
* Write a PROGMEM string to a file.
|
||||
|
20
Marlin/src/sd/SdFile.h
Executable file → Normal file
20
Marlin/src/sd/SdFile.h
Executable file → Normal file
@@ -16,17 +16,14 @@
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \brief SdFile class
|
||||
*/
|
||||
|
||||
/**
|
||||
* sd/SdFile.h
|
||||
*
|
||||
* Arduino SdFat Library
|
||||
* Copyright (c) 2009 by William Greiman
|
||||
*
|
||||
@@ -36,24 +33,23 @@
|
||||
#include "SdBaseFile.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* \class SdFile
|
||||
* \brief SdBaseFile with Print.
|
||||
*/
|
||||
class SdFile : public SdBaseFile/*, public Print*/ {
|
||||
class SdFile : public SdBaseFile {
|
||||
public:
|
||||
SdFile() {}
|
||||
SdFile(const char* name, uint8_t oflag);
|
||||
SdFile(const char *name, uint8_t oflag);
|
||||
#if ARDUINO >= 100
|
||||
size_t write(uint8_t b);
|
||||
#else
|
||||
void write(uint8_t b);
|
||||
void write(uint8_t b);
|
||||
#endif
|
||||
|
||||
int16_t write(const void* buf, uint16_t nbyte);
|
||||
void write(const char* str);
|
||||
int16_t write(const void *buf, uint16_t nbyte);
|
||||
void write(const char *str);
|
||||
void write_P(PGM_P str);
|
||||
void writeln_P(PGM_P str);
|
||||
};
|
||||
|
4
Marlin/src/sd/SdInfo.h
Executable file → Normal file
4
Marlin/src/sd/SdInfo.h
Executable file → Normal file
@@ -16,7 +16,7 @@
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
@@ -39,7 +39,7 @@
|
||||
// Version 3.01
|
||||
// May 18, 2010
|
||||
//
|
||||
// http://www.sdcard.org/developers/tech/sdcard/pls/simplified_specs
|
||||
// https://www.sdcard.org/downloads/pls/index.html
|
||||
|
||||
// SD card commands
|
||||
uint8_t const CMD0 = 0x00, // GO_IDLE_STATE - init card in spi mode if CS low
|
||||
|
46
Marlin/src/sd/SdVolume.cpp
Executable file → Normal file
46
Marlin/src/sd/SdVolume.cpp
Executable file → Normal file
@@ -16,11 +16,13 @@
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* sd/SdVolume.cpp
|
||||
*
|
||||
* Arduino SdFat Library
|
||||
* Copyright (c) 2009 by William Greiman
|
||||
*
|
||||
@@ -39,13 +41,15 @@
|
||||
// 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) {
|
||||
bool SdVolume::allocContiguous(uint32_t count, uint32_t *curCluster) {
|
||||
if (ENABLED(SDCARD_READONLY)) return false;
|
||||
|
||||
// start of group
|
||||
uint32_t bgnCluster;
|
||||
// end of group
|
||||
@@ -117,18 +121,20 @@ bool SdVolume::allocContiguous(uint32_t count, uint32_t* curCluster) {
|
||||
}
|
||||
|
||||
bool SdVolume::cacheFlush() {
|
||||
if (cacheDirty_) {
|
||||
if (!sdCard_->writeBlock(cacheBlockNumber_, cacheBuffer_.data))
|
||||
return false;
|
||||
|
||||
// mirror FAT tables
|
||||
if (cacheMirrorBlock_) {
|
||||
if (!sdCard_->writeBlock(cacheMirrorBlock_, cacheBuffer_.data))
|
||||
#if DISABLED(SDCARD_READONLY)
|
||||
if (cacheDirty_) {
|
||||
if (!sdCard_->writeBlock(cacheBlockNumber_, cacheBuffer_.data))
|
||||
return false;
|
||||
cacheMirrorBlock_ = 0;
|
||||
|
||||
// mirror FAT tables
|
||||
if (cacheMirrorBlock_) {
|
||||
if (!sdCard_->writeBlock(cacheMirrorBlock_, cacheBuffer_.data))
|
||||
return false;
|
||||
cacheMirrorBlock_ = 0;
|
||||
}
|
||||
cacheDirty_ = 0;
|
||||
}
|
||||
cacheDirty_ = 0;
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -143,7 +149,7 @@ bool SdVolume::cacheRawBlock(uint32_t blockNumber, bool dirty) {
|
||||
}
|
||||
|
||||
// return the size in bytes of a cluster chain
|
||||
bool SdVolume::chainSize(uint32_t cluster, uint32_t* size) {
|
||||
bool SdVolume::chainSize(uint32_t cluster, uint32_t *size) {
|
||||
uint32_t s = 0;
|
||||
do {
|
||||
if (!fatGet(cluster, &cluster)) return false;
|
||||
@@ -154,7 +160,7 @@ bool SdVolume::chainSize(uint32_t cluster, uint32_t* size) {
|
||||
}
|
||||
|
||||
// Fetch a FAT entry
|
||||
bool SdVolume::fatGet(uint32_t cluster, uint32_t* value) {
|
||||
bool SdVolume::fatGet(uint32_t cluster, uint32_t *value) {
|
||||
uint32_t lba;
|
||||
if (cluster > (clusterCount_ + 1)) return false;
|
||||
if (FAT12_SUPPORT && fatType_ == 12) {
|
||||
@@ -190,6 +196,8 @@ bool SdVolume::fatGet(uint32_t cluster, uint32_t* value) {
|
||||
|
||||
// Store a FAT entry
|
||||
bool SdVolume::fatPut(uint32_t cluster, uint32_t value) {
|
||||
if (ENABLED(SDCARD_READONLY)) return false;
|
||||
|
||||
uint32_t lba;
|
||||
// error if reserved cluster
|
||||
if (cluster < 2) return false;
|
||||
@@ -318,9 +326,9 @@ 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;
|
||||
fat32_boot_t *fbs;
|
||||
|
||||
sdCard_ = dev;
|
||||
fatType_ = 0;
|
||||
@@ -334,7 +342,7 @@ bool SdVolume::init(Sd2Card* dev, uint8_t part) {
|
||||
if (part) {
|
||||
if (part > 4) return false;
|
||||
if (!cacheRawBlock(volumeStartBlock, CACHE_FOR_READ)) return false;
|
||||
part_t* p = &cacheBuffer_.mbr.part[part - 1];
|
||||
part_t *p = &cacheBuffer_.mbr.part[part - 1];
|
||||
if ((p->boot & 0x7F) != 0 || p->totalSectors < 100 || p->firstSector == 0)
|
||||
return false; // not a valid partition
|
||||
volumeStartBlock = p->firstSector;
|
||||
|
44
Marlin/src/sd/SdVolume.h
Executable file → Normal file
44
Marlin/src/sd/SdVolume.h
Executable file → Normal file
@@ -16,17 +16,14 @@
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \brief SdVolume class
|
||||
*/
|
||||
|
||||
/**
|
||||
* sd/SdVolume.h
|
||||
*
|
||||
* Arduino SdFat Library
|
||||
* Copyright (c) 2009 by William Greiman
|
||||
*
|
||||
@@ -39,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
|
||||
|
||||
@@ -50,6 +49,7 @@
|
||||
|
||||
//==============================================================================
|
||||
// SdVolume class
|
||||
|
||||
/**
|
||||
* \brief Cache for an SD data block
|
||||
*/
|
||||
@@ -87,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.
|
||||
@@ -115,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
|
||||
@@ -127,7 +127,7 @@ class SdVolume {
|
||||
* \param[out] v value of entry
|
||||
* \return true for success or false for failure
|
||||
*/
|
||||
bool dbgFat(uint32_t n, uint32_t* v) { return fatGet(n, v); }
|
||||
bool dbgFat(uint32_t n, uint32_t *v) { return fatGet(n, v); }
|
||||
|
||||
private:
|
||||
// Allow SdBaseFile access to SdVolume private data.
|
||||
@@ -141,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
|
||||
@@ -164,7 +164,7 @@ class SdVolume {
|
||||
uint16_t rootDirEntryCount_; // number of entries in FAT16 root dir
|
||||
uint32_t rootDirStart_; // root start block for FAT16, cluster for FAT32
|
||||
|
||||
bool allocContiguous(uint32_t count, uint32_t* curCluster);
|
||||
bool allocContiguous(uint32_t count, uint32_t *curCluster);
|
||||
uint8_t blockOfCluster(uint32_t position) const { return (position >> 9) & (blocksPerCluster_ - 1); }
|
||||
uint32_t clusterStartBlock(uint32_t cluster) const { return dataStartBlock_ + ((cluster - 2) << clusterSizeShift_); }
|
||||
uint32_t blockNumber(uint32_t cluster, uint32_t position) const { return clusterStartBlock(cluster) + blockOfCluster(position); }
|
||||
@@ -186,8 +186,8 @@ class SdVolume {
|
||||
cacheBlockNumber_ = blockNumber;
|
||||
}
|
||||
void cacheSetDirty() { cacheDirty_ |= CACHE_FOR_WRITE; }
|
||||
bool chainSize(uint32_t beginCluster, uint32_t* size);
|
||||
bool fatGet(uint32_t cluster, uint32_t* value);
|
||||
bool chainSize(uint32_t beginCluster, uint32_t *size);
|
||||
bool fatGet(uint32_t cluster, uint32_t *value);
|
||||
bool fatPut(uint32_t cluster, uint32_t value);
|
||||
bool fatPutEOC(uint32_t cluster) { return fatPut(cluster, 0x0FFFFFFF); }
|
||||
bool freeChain(uint32_t cluster);
|
||||
@@ -196,6 +196,6 @@ class SdVolume {
|
||||
if (fatType_ == 16) return cluster >= FAT16EOC_MIN;
|
||||
return cluster >= FAT32EOC_MIN;
|
||||
}
|
||||
bool readBlock(uint32_t block, uint8_t* dst) { return sdCard_->readBlock(block, dst); }
|
||||
bool writeBlock(uint32_t block, const uint8_t* dst) { return sdCard_->writeBlock(block, dst); }
|
||||
bool readBlock(uint32_t block, uint8_t *dst) { return sdCard_->readBlock(block, dst); }
|
||||
bool writeBlock(uint32_t block, const uint8_t *dst) { return sdCard_->writeBlock(block, dst); }
|
||||
};
|
||||
|
809
Marlin/src/sd/cardreader.cpp
Executable file → Normal file
809
Marlin/src/sd/cardreader.cpp
Executable file → Normal file
File diff suppressed because it is too large
Load Diff
224
Marlin/src/sd/cardreader.h
Executable file → Normal file
224
Marlin/src/sd/cardreader.h
Executable file → Normal file
@@ -16,7 +16,7 @@
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
@@ -25,18 +25,57 @@
|
||||
|
||||
#if ENABLED(SDSUPPORT)
|
||||
|
||||
#define SD_RESORT BOTH(SDCARD_SORT_ALPHA, SDSORT_DYNAMIC_RAM)
|
||||
extern const char M23_STR[], M24_STR[];
|
||||
|
||||
#if ENABLED(SDCARD_SORT_ALPHA)
|
||||
#if ENABLED(SDSORT_DYNAMIC_RAM)
|
||||
#define SD_RESORT 1
|
||||
#endif
|
||||
#if FOLDER_SORTING || ENABLED(SDSORT_GCODE)
|
||||
#define HAS_FOLDER_SORTING 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if ENABLED(SDCARD_RATHERRECENTFIRST) && DISABLED(SDCARD_SORT_ALPHA)
|
||||
#define SD_ORDER(N,C) ((C) - 1 - (N))
|
||||
#else
|
||||
#define SD_ORDER(N,C) N
|
||||
#endif
|
||||
|
||||
#define MAX_DIR_DEPTH 10 // Maximum folder depth
|
||||
#define MAXDIRNAMELENGTH 8 // DOS folder name size
|
||||
#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,
|
||||
logging:1,
|
||||
sdprinting:1,
|
||||
sdprintdone:1,
|
||||
mounted:1,
|
||||
filenameIsDir:1,
|
||||
workDirIsRoot:1,
|
||||
@@ -47,6 +86,10 @@ typedef struct {
|
||||
;
|
||||
} card_flags_t;
|
||||
|
||||
#if ENABLED(AUTO_REPORT_SD_STATUS)
|
||||
#include "../libs/autoreport.h"
|
||||
#endif
|
||||
|
||||
class CardReader {
|
||||
public:
|
||||
static card_flags_t flag; // Flags (above)
|
||||
@@ -55,10 +98,10 @@ public:
|
||||
|
||||
// Fast! binary file transfer
|
||||
#if ENABLED(BINARY_FILE_TRANSFER)
|
||||
#if NUM_SERIAL > 1
|
||||
static int8_t transfer_port_index;
|
||||
#if HAS_MULTI_SERIAL
|
||||
static serial_index_t transfer_port_index;
|
||||
#else
|
||||
static constexpr int8_t transfer_port_index = 0;
|
||||
static constexpr serial_index_t transfer_port_index = 0;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -66,26 +109,33 @@ public:
|
||||
|
||||
CardReader();
|
||||
|
||||
static void changeMedia(DiskIODriver *_driver) { driver = _driver; }
|
||||
|
||||
static SdFile getroot() { return root; }
|
||||
|
||||
static void mount();
|
||||
static void release();
|
||||
static inline bool isMounted() { return flag.mounted; }
|
||||
static void ls();
|
||||
|
||||
// Handle media insert/remove
|
||||
static void manage_media();
|
||||
|
||||
// SD Card Logging
|
||||
static void openLogFile(char * const path);
|
||||
static void openLogFile(const char * const path);
|
||||
static void write_command(char * const buf);
|
||||
|
||||
// Auto-Start files
|
||||
static int8_t autostart_index; // Index of autoX.g files
|
||||
static void beginautostart();
|
||||
static void checkautostart();
|
||||
#if DISABLED(NO_SD_AUTOSTART) // Auto-Start auto#.g file handling
|
||||
static uint8_t autofile_index; // Next auto#.g index to run, plus one. Ignored by autofile_check when zero.
|
||||
static void autofile_begin(); // Begin check. Called automatically after boot-up.
|
||||
static bool autofile_check(); // Check for the next auto-start file and run it.
|
||||
static inline void autofile_cancel() { autofile_index = 0; }
|
||||
#endif
|
||||
|
||||
// Basic file ops
|
||||
static void openFileRead(char * const path, const uint8_t subcall=0);
|
||||
static void openFileWrite(char * const path);
|
||||
static void openFileRead(const char * const path, const uint8_t subcall=0);
|
||||
static void openFileWrite(const char * const path);
|
||||
static void closefile(const bool store_location=false);
|
||||
static bool fileExists(const char * const name);
|
||||
static void removeFile(const char * const name);
|
||||
|
||||
static inline char* longest_filename() { return longFilename[0] ? longFilename : filename; }
|
||||
@@ -102,71 +152,101 @@ public:
|
||||
|
||||
// Select a file
|
||||
static void selectFileByIndex(const uint16_t nr);
|
||||
static void selectFileByName(const char* const match);
|
||||
static void selectFileByName(const char * const match); // (working directory only)
|
||||
|
||||
// Print job
|
||||
static void openAndPrintFile(const char *name); // (working directory)
|
||||
static void fileHasFinished();
|
||||
static void getAbsFilename(char *dst);
|
||||
static void printFilename();
|
||||
static void startFileprint();
|
||||
static void endFilePrint(
|
||||
#if SD_RESORT
|
||||
const bool re_sort=false
|
||||
#endif
|
||||
);
|
||||
static void report_status();
|
||||
static inline void pauseSDPrint() { flag.sdprinting = false; }
|
||||
static inline bool isPaused() { return isFileOpen() && !flag.sdprinting; }
|
||||
static inline bool isPrinting() { return flag.sdprinting; }
|
||||
static void getAbsFilenameInCWD(char *dst);
|
||||
static void printSelectedFilename();
|
||||
static void openAndPrintFile(const char *name); // (working directory or full path)
|
||||
static void startOrResumeFilePrinting();
|
||||
static void endFilePrintNow(TERN_(SD_RESORT, const bool re_sort=false));
|
||||
static void abortFilePrintNow(TERN_(SD_RESORT, const bool re_sort=false));
|
||||
static void fileHasFinished();
|
||||
static inline void abortFilePrintSoon() { flag.abort_sd_printing = true; }
|
||||
static inline void pauseSDPrint() { flag.sdprinting = false; }
|
||||
static inline bool isPrinting() { return flag.sdprinting; }
|
||||
static inline bool isPaused() { return isFileOpen() && !isPrinting(); }
|
||||
#if HAS_PRINT_PROGRESS_PERMYRIAD
|
||||
static inline uint16_t permyriadDone() { return (isFileOpen() && filesize) ? sdpos / ((filesize + 9999) / 10000) : 0; }
|
||||
static inline uint16_t permyriadDone() {
|
||||
if (flag.sdprintdone) return 10000;
|
||||
if (isFileOpen() && filesize) return sdpos / ((filesize + 9999) / 10000);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
static inline uint8_t percentDone() { return (isFileOpen() && filesize) ? sdpos / ((filesize + 99) / 100) : 0; }
|
||||
static inline uint8_t percentDone() {
|
||||
if (flag.sdprintdone) return 100;
|
||||
if (isFileOpen() && filesize) return sdpos / ((filesize + 99) / 100);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Helper for open and remove
|
||||
static const char* diveToFile(const bool update_cwd, SdFile*& curDir, const char * const path, const bool echo=false);
|
||||
/**
|
||||
* Dive down to a relative or absolute path.
|
||||
* Relative paths apply to the workDir.
|
||||
*
|
||||
* update_cwd: Pass 'true' to update the workDir on success.
|
||||
* inDirPtr: On exit your pointer points to the target SdFile.
|
||||
* A nullptr indicates failure.
|
||||
* path: Start with '/' for abs path. End with '/' to get a folder ref.
|
||||
* echo: Set 'true' to print the path throughout the loop.
|
||||
*/
|
||||
static const char* diveToFile(const bool update_cwd, SdFile* &inDirPtr, const char * const path, const bool echo=false);
|
||||
|
||||
#if ENABLED(SDCARD_SORT_ALPHA)
|
||||
static void presort();
|
||||
static void getfilename_sorted(const uint16_t nr);
|
||||
#if ENABLED(SDSORT_GCODE)
|
||||
FORCE_INLINE static void setSortOn(bool b) { sort_alpha = b; presort(); }
|
||||
FORCE_INLINE static void setSortFolders(int i) { sort_folders = i; presort(); }
|
||||
FORCE_INLINE static void setSortOn(bool b) { sort_alpha = b; presort(); }
|
||||
FORCE_INLINE static void setSortFolders(int i) { sort_folders = i; presort(); }
|
||||
//FORCE_INLINE static void setSortReverse(bool b) { sort_reverse = b; }
|
||||
#endif
|
||||
#else
|
||||
FORCE_INLINE static void getfilename_sorted(const uint16_t nr) { selectFileByIndex(nr); }
|
||||
#endif
|
||||
|
||||
static void ls(TERN_(LONG_FILENAME_HOST_SUPPORT, bool includeLongNames=false));
|
||||
|
||||
#if ENABLED(POWER_LOSS_RECOVERY)
|
||||
static bool jobRecoverFileExists();
|
||||
static void openJobRecoveryFile(const bool read);
|
||||
static void removeJobRecoveryFile();
|
||||
#endif
|
||||
|
||||
static inline bool isFileOpen() { return isMounted() && file.isOpen(); }
|
||||
static inline uint32_t getIndex() { return sdpos; }
|
||||
static inline bool eof() { return sdpos >= filesize; }
|
||||
static inline void setIndex(const uint32_t index) { sdpos = index; file.seekSet(index); }
|
||||
static inline char* getWorkDirName() { workDir.getDosName(filename); return filename; }
|
||||
static inline int16_t get() { sdpos = file.curPosition(); return (int16_t)file.read(); }
|
||||
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 inline long GetLastSDpos() { return sdpos; };
|
||||
// Current Working Dir - Set by cd, cdup, cdroot, and diveToFile(true, ...)
|
||||
static inline char* getWorkDirName() { workDir.getDosName(filename); return filename; }
|
||||
static inline SdFile& getWorkDir() { return workDir.isOpen() ? workDir : root; }
|
||||
|
||||
static Sd2Card& getSd2Card() { return sd2card; }
|
||||
// Print File stats
|
||||
static inline uint32_t getFileSize() { return filesize; }
|
||||
static inline uint32_t getIndex() { return sdpos; }
|
||||
static inline bool isFileOpen() { return isMounted() && file.isOpen(); }
|
||||
static inline bool eof() { return getIndex() >= getFileSize(); }
|
||||
|
||||
// File data operations
|
||||
static inline int16_t get() { int16_t out = (int16_t)file.read(); sdpos = file.curPosition(); return out; }
|
||||
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 inline void setIndex(const uint32_t index) { file.seekSet((sdpos = index)); }
|
||||
|
||||
// TODO: rename to diskIODriver()
|
||||
static DiskIODriver* diskIODriver() { return driver; }
|
||||
|
||||
#if ENABLED(AUTO_REPORT_SD_STATUS)
|
||||
static void auto_report_sd_status();
|
||||
static inline void set_auto_report_interval(uint8_t v) {
|
||||
#if NUM_SERIAL > 1
|
||||
auto_report_port = serial_port_index;
|
||||
#endif
|
||||
NOMORE(v, 60);
|
||||
auto_report_sd_interval = v;
|
||||
next_sd_report_ms = millis() + 1000UL * v;
|
||||
}
|
||||
//
|
||||
// SD Auto Reporting
|
||||
//
|
||||
struct AutoReportSD { static void report() { report_status(); } };
|
||||
static AutoReporter<AutoReportSD> auto_reporter;
|
||||
#endif
|
||||
|
||||
#if SHARED_VOLUME_IS(USB_FLASH_DRIVE) || ENABLED(USB_FLASH_DRIVE_SUPPORT)
|
||||
#define HAS_USB_FLASH_DRIVE 1
|
||||
static DiskIODriver_USBFlash media_driver_usbFlash;
|
||||
#endif
|
||||
|
||||
#if NEED_SD2CARD_SDIO || NEED_SD2CARD_SPI
|
||||
typedef TERN(NEED_SD2CARD_SDIO, DiskIODriver_SDIO, DiskIODriver_SPI_SD) sdcard_driver_t;
|
||||
static sdcard_driver_t media_driver_sdcard;
|
||||
#endif
|
||||
|
||||
private:
|
||||
@@ -224,7 +304,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
|
||||
|
||||
@@ -232,31 +312,20 @@ private:
|
||||
|
||||
#endif // SDCARD_SORT_ALPHA
|
||||
|
||||
static Sd2Card sd2card;
|
||||
static DiskIODriver *driver;
|
||||
static SdVolume volume;
|
||||
static SdFile file;
|
||||
|
||||
static uint32_t filesize, sdpos;
|
||||
static uint32_t filesize, // Total size of the current file, in bytes
|
||||
sdpos; // Index most recently read (one behind file.getPos)
|
||||
|
||||
//
|
||||
// Procedure calls to other files
|
||||
//
|
||||
#ifndef SD_PROCEDURE_DEPTH
|
||||
#define SD_PROCEDURE_DEPTH 1
|
||||
#endif
|
||||
static uint8_t file_subcall_ctr;
|
||||
static uint32_t filespos[SD_PROCEDURE_DEPTH];
|
||||
static char proc_filenames[SD_PROCEDURE_DEPTH][MAXPATHNAMELENGTH];
|
||||
|
||||
//
|
||||
// SD Auto Reporting
|
||||
//
|
||||
#if ENABLED(AUTO_REPORT_SD_STATUS)
|
||||
static uint8_t auto_report_sd_interval;
|
||||
static millis_t next_sd_report_ms;
|
||||
#if NUM_SERIAL > 1
|
||||
static serial_index_t auto_report_port;
|
||||
#endif
|
||||
#if HAS_MEDIA_SUBCALLS
|
||||
static uint8_t file_subcall_ctr;
|
||||
static uint32_t filespos[SD_PROCEDURE_DEPTH];
|
||||
static char proc_filenames[SD_PROCEDURE_DEPTH][MAXPATHNAMELENGTH];
|
||||
#endif
|
||||
|
||||
//
|
||||
@@ -266,7 +335,12 @@ private:
|
||||
static int countItems(SdFile dir);
|
||||
static void selectByIndex(SdFile dir, const uint8_t index);
|
||||
static void selectByName(SdFile dir, const char * const match);
|
||||
static void printListing(SdFile parent, const char * const prepend=nullptr);
|
||||
static void printListing(
|
||||
SdFile parent
|
||||
OPTARG(LONG_FILENAME_HOST_SUPPORT, const bool includeLongNames=false)
|
||||
, const char * const prepend=nullptr
|
||||
OPTARG(LONG_FILENAME_HOST_SUPPORT, const char * const prependLong=nullptr)
|
||||
);
|
||||
|
||||
#if ENABLED(SDCARD_SORT_ALPHA)
|
||||
static void flush_presort();
|
||||
@@ -274,7 +348,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
|
||||
@@ -282,7 +356,8 @@ private:
|
||||
#define IS_SD_INSERTED() true
|
||||
#endif
|
||||
|
||||
#define IS_SD_PRINTING() card.flag.sdprinting
|
||||
#define IS_SD_PRINTING() (card.flag.sdprinting && !card.flag.abort_sd_printing)
|
||||
#define IS_SD_FETCHING() (!card.flag.sdprintdone && IS_SD_PRINTING())
|
||||
#define IS_SD_PAUSED() card.isPaused()
|
||||
#define IS_SD_FILE_OPEN() card.isFileOpen()
|
||||
|
||||
@@ -291,6 +366,7 @@ extern CardReader card;
|
||||
#else // !SDSUPPORT
|
||||
|
||||
#define IS_SD_PRINTING() false
|
||||
#define IS_SD_FETCHING() false
|
||||
#define IS_SD_PAUSED() false
|
||||
#define IS_SD_FILE_OPEN() false
|
||||
|
||||
|
67
Marlin/src/sd/disk_io_driver.h
Normal file
67
Marlin/src/sd/disk_io_driver.h
Normal 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 Interface
|
||||
*
|
||||
* 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;
|
||||
};
|
92
Marlin/src/sd/usb_flashdrive/Sd2Card_FlashDrive.cpp
Executable file → Normal file
92
Marlin/src/sd/usb_flashdrive/Sd2Card_FlashDrive.cpp
Executable file → Normal file
@@ -16,7 +16,7 @@
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -34,9 +34,9 @@
|
||||
#define USB_STARTUP_DELAY 0
|
||||
|
||||
// uncomment to get 'printf' console debugging. NOT FOR UNO!
|
||||
//#define HOST_DEBUG(...) {char s[255]; sprintf(s,__VA_ARGS__); SERIAL_ECHOLNPAIR("UHS:",s);}
|
||||
//#define BS_HOST_DEBUG(...) {char s[255]; sprintf(s,__VA_ARGS__); SERIAL_ECHOLNPAIR("UHS:",s);}
|
||||
//#define MAX_HOST_DEBUG(...) {char s[255]; sprintf(s,__VA_ARGS__); SERIAL_ECHOLNPAIR("UHS:",s);}
|
||||
//#define HOST_DEBUG(...) {char s[255]; sprintf(s,__VA_ARGS__); SERIAL_ECHOLNPGM("UHS:",s);}
|
||||
//#define BS_HOST_DEBUG(...) {char s[255]; sprintf(s,__VA_ARGS__); SERIAL_ECHOLNPGM("UHS:",s);}
|
||||
//#define MAX_HOST_DEBUG(...) {char s[255]; sprintf(s,__VA_ARGS__); SERIAL_ECHOLNPGM("UHS:",s);}
|
||||
|
||||
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
|
||||
|
||||
@@ -44,16 +44,17 @@
|
||||
#include "../../core/serial.h"
|
||||
#include "../../module/temperature.h"
|
||||
|
||||
static_assert(USB_CS_PIN != -1, "USB_CS_PIN must be defined");
|
||||
static_assert(USB_INTR_PIN != -1, "USB_INTR_PIN must be defined");
|
||||
#if DISABLED(USE_OTG_USB_HOST) && !PINS_EXIST(USB_CS, USB_INTR)
|
||||
#error "USB_FLASH_DRIVE_SUPPORT requires USB_CS_PIN and USB_INTR_PIN to be defined."
|
||||
#endif
|
||||
|
||||
#if ENABLED(USE_UHS3_USB)
|
||||
#define NO_AUTO_SPEED
|
||||
#define UHS_MAX3421E_SPD 8000000 >> SPI_SPEED
|
||||
#define UHS_MAX3421E_SPD 8000000 >> SD_SPI_SPEED
|
||||
#define UHS_DEVICE_WINDOWS_USB_SPEC_VIOLATION_DESCRIPTOR_DEVICE 1
|
||||
#define UHS_HOST_MAX_INTERFACE_DRIVERS 2
|
||||
#define MASS_MAX_SUPPORTED_LUN 1
|
||||
#define USB_HOST_SERIAL MYSERIAL0
|
||||
#define USB_HOST_SERIAL MYSERIAL1
|
||||
|
||||
// Workaround for certain issues with UHS3
|
||||
#define SKIP_PAGE3F // Required for IOGEAR media adapter
|
||||
@@ -81,6 +82,17 @@ static_assert(USB_INTR_PIN != -1, "USB_INTR_PIN must be defined");
|
||||
|
||||
#define UHS_START (usb.Init() == 0)
|
||||
#define UHS_STATE(state) UHS_USB_HOST_STATE_##state
|
||||
#elif ENABLED(USE_OTG_USB_HOST)
|
||||
|
||||
#if HAS_SD_HOST_DRIVE
|
||||
#include HAL_PATH(../../HAL, msc_sd.h)
|
||||
#endif
|
||||
|
||||
#include HAL_PATH(../../HAL, usb_host.h)
|
||||
|
||||
#define UHS_START usb.start()
|
||||
#define rREVISION 0
|
||||
#define UHS_STATE(state) USB_STATE_##state
|
||||
#else
|
||||
#include "lib-uhs2/Usb.h"
|
||||
#include "lib-uhs2/masstorage.h"
|
||||
@@ -94,9 +106,7 @@ static_assert(USB_INTR_PIN != -1, "USB_INTR_PIN must be defined");
|
||||
|
||||
#include "Sd2Card_FlashDrive.h"
|
||||
|
||||
#if HAS_DISPLAY
|
||||
#include "../../lcd/ultralcd.h"
|
||||
#endif
|
||||
#include "../../lcd/marlinui.h"
|
||||
|
||||
static enum {
|
||||
UNINITIALIZED,
|
||||
@@ -111,14 +121,12 @@ 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) {
|
||||
SERIAL_ECHOLNPGM(" failed.");
|
||||
#if EITHER(ULTRA_LCD, EXTENSIBLE_UI)
|
||||
LCD_MESSAGEPGM(MSG_MEDIA_USB_FAILED);
|
||||
#endif
|
||||
LCD_MESSAGEPGM(MSG_MEDIA_USB_FAILED);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -139,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();
|
||||
@@ -162,7 +170,7 @@ void Sd2Card::idle() {
|
||||
UHS_USB_DEBUG(CONFIGURING_DONE);
|
||||
UHS_USB_DEBUG(RUNNING);
|
||||
default:
|
||||
SERIAL_ECHOLNPAIR("UHS_USB_HOST_STATE: ", task_state);
|
||||
SERIAL_ECHOLNPGM("UHS_USB_HOST_STATE: ", task_state);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -213,9 +221,7 @@ void Sd2Card::idle() {
|
||||
#if USB_DEBUG >= 1
|
||||
SERIAL_ECHOLNPGM("Waiting for media");
|
||||
#endif
|
||||
#if EITHER(ULTRA_LCD, EXTENSIBLE_UI)
|
||||
LCD_MESSAGEPGM(MSG_MEDIA_WAITING);
|
||||
#endif
|
||||
LCD_MESSAGEPGM(MSG_MEDIA_WAITING);
|
||||
GOTO_STATE_AFTER_DELAY(state, 2000);
|
||||
}
|
||||
break;
|
||||
@@ -229,11 +235,9 @@ void Sd2Card::idle() {
|
||||
#if USB_DEBUG >= 1
|
||||
SERIAL_ECHOLNPGM("USB device removed");
|
||||
#endif
|
||||
#if EITHER(ULTRA_LCD, EXTENSIBLE_UI)
|
||||
if (state != MEDIA_READY)
|
||||
LCD_MESSAGEPGM(MSG_MEDIA_USB_REMOVED);
|
||||
#endif
|
||||
GOTO_STATE_AFTER_DELAY( WAIT_FOR_DEVICE, 0 );
|
||||
if (state != MEDIA_READY)
|
||||
LCD_MESSAGEPGM(MSG_MEDIA_USB_REMOVED);
|
||||
GOTO_STATE_AFTER_DELAY(WAIT_FOR_DEVICE, 0);
|
||||
}
|
||||
|
||||
else if (state > WAIT_FOR_LUN && !bulk.LUNIsGood(0)) {
|
||||
@@ -241,52 +245,48 @@ void Sd2Card::idle() {
|
||||
#if USB_DEBUG >= 1
|
||||
SERIAL_ECHOLNPGM("Media removed");
|
||||
#endif
|
||||
#if EITHER(ULTRA_LCD, EXTENSIBLE_UI)
|
||||
LCD_MESSAGEPGM(MSG_MEDIA_REMOVED);
|
||||
#endif
|
||||
GOTO_STATE_AFTER_DELAY( WAIT_FOR_DEVICE, 0 );
|
||||
LCD_MESSAGEPGM(MSG_MEDIA_REMOVED);
|
||||
GOTO_STATE_AFTER_DELAY(WAIT_FOR_DEVICE, 0);
|
||||
}
|
||||
|
||||
else if (task_state == UHS_STATE(ERROR)) {
|
||||
#if EITHER(ULTRA_LCD, EXTENSIBLE_UI)
|
||||
LCD_MESSAGEPGM(MSG_MEDIA_READ_ERROR);
|
||||
#endif
|
||||
GOTO_STATE_AFTER_DELAY( MEDIA_ERROR, 0 );
|
||||
LCD_MESSAGEPGM(MSG_MEDIA_READ_ERROR);
|
||||
GOTO_STATE_AFTER_DELAY(MEDIA_ERROR, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 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::ready() {
|
||||
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
|
||||
const uint32_t sectorSize = bulk.GetSectorSize(0);
|
||||
if (sectorSize != 512) {
|
||||
SERIAL_ECHOLNPAIR("Expecting sector size of 512. Got: ", sectorSize);
|
||||
SERIAL_ECHOLNPGM("Expecting sector size of 512. Got: ", sectorSize);
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if USB_DEBUG >= 3
|
||||
lun0_capacity = bulk.GetCapacity(0);
|
||||
SERIAL_ECHOLNPAIR("LUN Capacity (in blocks): ", lun0_capacity);
|
||||
SERIAL_ECHOLNPGM("LUN Capacity (in blocks): ", lun0_capacity);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
// 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,29 +295,29 @@ 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) {
|
||||
SERIAL_ECHOLNPAIR("Attempt to read past end of LUN: ", block);
|
||||
SERIAL_ECHOLNPGM("Attempt to read past end of LUN: ", block);
|
||||
return false;
|
||||
}
|
||||
#if USB_DEBUG >= 4
|
||||
SERIAL_ECHOLNPAIR("Read block ", block);
|
||||
SERIAL_ECHOLNPGM("Read block ", block);
|
||||
#endif
|
||||
#endif
|
||||
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) {
|
||||
SERIAL_ECHOLNPAIR("Attempt to write past end of LUN: ", block);
|
||||
SERIAL_ECHOLNPGM("Attempt to write past end of LUN: ", block);
|
||||
return false;
|
||||
}
|
||||
#if USB_DEBUG >= 4
|
||||
SERIAL_ECHOLNPAIR("Write block ", block);
|
||||
SERIAL_ECHOLNPGM("Write block ", block);
|
||||
#endif
|
||||
#endif
|
||||
return bulk.Write(0, block, 512, 1, src) == 0;
|
||||
|
76
Marlin/src/sd/usb_flashdrive/Sd2Card_FlashDrive.h
Executable file → Normal file
76
Marlin/src/sd/usb_flashdrive/Sd2Card_FlashDrive.h
Executable file → Normal file
@@ -16,35 +16,38 @@
|
||||
* 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 <http://www.gnu.org/licenses/>.
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* \file
|
||||
* \brief Sd2Card class for V2 SD/SDHC cards
|
||||
* \brief Sd2Card class for USB Flash Drive
|
||||
*/
|
||||
|
||||
#include "../SdFatConfig.h"
|
||||
#include "../SdInfo.h"
|
||||
#include "../disk_io_driver.h"
|
||||
|
||||
/**
|
||||
* define SOFTWARE_SPI to use bit-bang SPI
|
||||
*/
|
||||
#if MEGA_SOFT_SPI || USE_SOFTWARE_SPI
|
||||
#define SOFTWARE_SPI
|
||||
#if DISABLED(USE_OTG_USB_HOST)
|
||||
/**
|
||||
* Define SOFTWARE_SPI to use bit-bang SPI
|
||||
*/
|
||||
#if EITHER(MEGA_SOFT_SPI, USE_SOFTWARE_SPI)
|
||||
#define SOFTWARE_SPI
|
||||
#endif
|
||||
|
||||
// SPI pin definitions - do not edit here - change in SdFatConfig.h
|
||||
#if ENABLED(SOFTWARE_SPI)
|
||||
#warning "Auto-assigning '10' as the SD_CHIP_SELECT_PIN."
|
||||
#define SD_CHIP_SELECT_PIN 10 // Software SPI chip select pin for the SD
|
||||
#else
|
||||
// hardware pin defs
|
||||
#define SD_CHIP_SELECT_PIN SD_SS_PIN // The default chip select pin for the SD card is SS.
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// SPI pin definitions - do not edit here - change in SdFatConfig.h
|
||||
#if DISABLED(SOFTWARE_SPI)
|
||||
// hardware pin defs
|
||||
#define SD_CHIP_SELECT_PIN SS_PIN // The default chip select pin for the SD card is SS.
|
||||
#else // SOFTWARE_SPI
|
||||
#define SD_CHIP_SELECT_PIN 10 // Software SPI chip select pin for the SD
|
||||
#endif // SOFTWARE_SPI
|
||||
|
||||
class Sd2Card {
|
||||
class DiskIODriver_USBFlash : public DiskIODriver {
|
||||
private:
|
||||
uint32_t pos;
|
||||
|
||||
@@ -52,23 +55,26 @@ class Sd2Card {
|
||||
|
||||
public:
|
||||
static bool usbStartup();
|
||||
|
||||
bool init(const uint8_t sckRateID=0, const pin_t chipSelectPin=SD_CHIP_SELECT_PIN);
|
||||
|
||||
static void idle();
|
||||
|
||||
inline bool readStart(const uint32_t block) { pos = block; return ready(); }
|
||||
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 ready(); }
|
||||
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);
|
||||
|
||||
uint32_t cardSize();
|
||||
static bool isInserted();
|
||||
static bool ready();
|
||||
|
||||
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;
|
||||
};
|
||||
|
5
Marlin/src/sd/usb_flashdrive/lib-uhs2/README.txt
Executable file → Normal file
5
Marlin/src/sd/usb_flashdrive/lib-uhs2/README.txt
Executable file → Normal file
@@ -40,7 +40,4 @@ under the "MIT" license, as documented here:
|
||||
|
||||
==== MARLIN INTEGRATION WORK ====
|
||||
|
||||
All additional work done to integrate USB into Marlin was performed by AlephObjects, Inc.
|
||||
and is licensed under the GPLv3.
|
||||
|
||||
-- marcio@alephobjects.com
|
||||
All additional work done to integrate USB into Marlin was performed by LulzBot and is licensed under the GPLv3.
|
||||
|
303
Marlin/src/sd/usb_flashdrive/lib-uhs2/Usb.cpp
Executable file → Normal file
303
Marlin/src/sd/usb_flashdrive/lib-uhs2/Usb.cpp
Executable file → Normal file
@@ -19,10 +19,13 @@
|
||||
* -------------------
|
||||
*
|
||||
* Circuits At Home, LTD
|
||||
* Web : http://www.circuitsathome.com
|
||||
* Web : https://www.circuitsathome.com
|
||||
* e-mail : support@circuitsathome.com
|
||||
*/
|
||||
/* USB functions */
|
||||
|
||||
//
|
||||
// USB functions supporting Flash Drive
|
||||
//
|
||||
|
||||
#include "../../../inc/MarlinConfigPre.h"
|
||||
|
||||
@@ -35,7 +38,7 @@ static uint8_t usb_task_state;
|
||||
|
||||
/* constructor */
|
||||
USB::USB() : bmHubPre(0) {
|
||||
usb_task_state = USB_DETACHED_SUBSTATE_INITIALIZE; //set up state machine
|
||||
usb_task_state = USB_DETACHED_SUBSTATE_INITIALIZE; // Set up state machine
|
||||
init();
|
||||
}
|
||||
|
||||
@@ -45,13 +48,8 @@ void USB::init() {
|
||||
bmHubPre = 0;
|
||||
}
|
||||
|
||||
uint8_t USB::getUsbTaskState() {
|
||||
return usb_task_state;
|
||||
}
|
||||
|
||||
void USB::setUsbTaskState(uint8_t state) {
|
||||
usb_task_state = state;
|
||||
}
|
||||
uint8_t USB::getUsbTaskState() { return usb_task_state; }
|
||||
void USB::setUsbTaskState(uint8_t state) { usb_task_state = state; }
|
||||
|
||||
EpInfo* USB::getEpInfoEntry(uint8_t addr, uint8_t ep) {
|
||||
UsbDevice *p = addrPool.GetUsbDevicePtr(addr);
|
||||
@@ -70,9 +68,11 @@ EpInfo* USB::getEpInfoEntry(uint8_t addr, uint8_t ep) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* set device table entry */
|
||||
|
||||
/* each device is different and has different number of endpoints. This function plugs endpoint record structure, defined in application, to devtable */
|
||||
/**
|
||||
* Set device table entry
|
||||
* Each device is different and has different number of endpoints.
|
||||
* This function plugs endpoint record structure, defined in application, to devtable
|
||||
*/
|
||||
uint8_t USB::setEpInfoEntry(uint8_t addr, uint8_t epcount, EpInfo* eprecord_ptr) {
|
||||
if (!eprecord_ptr)
|
||||
return USB_ERROR_INVALID_ARGUMENT;
|
||||
@@ -112,7 +112,7 @@ uint8_t USB::SetAddress(uint8_t addr, uint8_t ep, EpInfo **ppep, uint16_t *nak_l
|
||||
USBTRACE2(" NAK Limit: ", nak_limit);
|
||||
USBTRACE("\r\n");
|
||||
*/
|
||||
regWr(rPERADDR, addr); //set peripheral address
|
||||
regWr(rPERADDR, addr); // Set peripheral address
|
||||
|
||||
uint8_t mode = regRd(rMODE);
|
||||
|
||||
@@ -121,8 +121,6 @@ uint8_t USB::SetAddress(uint8_t addr, uint8_t ep, EpInfo **ppep, uint16_t *nak_l
|
||||
//Serial.print("\r\nLS: ");
|
||||
//Serial.println(p->lowspeed, HEX);
|
||||
|
||||
|
||||
|
||||
// Set bmLOWSPEED and bmHUBPRE in case of low-speed device, reset them otherwise
|
||||
regWr(rMODE, (p->lowspeed) ? mode | bmLOWSPEED | bmHubPre : mode & ~(bmHUBPRE | bmLOWSPEED));
|
||||
|
||||
@@ -133,11 +131,10 @@ uint8_t USB::SetAddress(uint8_t addr, uint8_t ep, EpInfo **ppep, uint16_t *nak_l
|
||||
/* depending on request. Actual requests are defined as inlines */
|
||||
/* return codes: */
|
||||
/* 00 = success */
|
||||
|
||||
/* 01-0f = non-zero HRSLT */
|
||||
uint8_t USB::ctrlReq(uint8_t addr, uint8_t ep, uint8_t bmReqType, uint8_t bRequest, uint8_t wValLo, uint8_t wValHi,
|
||||
uint16_t wInd, uint16_t total, uint16_t nbytes, uint8_t* dataptr, USBReadParser *p) {
|
||||
bool direction = false; //request direction, IN or OUT
|
||||
uint16_t wInd, uint16_t total, uint16_t nbytes, uint8_t *dataptr, USBReadParser *p) {
|
||||
bool direction = false; // Request direction, IN or OUT
|
||||
uint8_t rcode;
|
||||
SETUP_PKT setup_pkt;
|
||||
|
||||
@@ -157,15 +154,15 @@ uint8_t USB::ctrlReq(uint8_t addr, uint8_t ep, uint8_t bmReqType, uint8_t bReque
|
||||
setup_pkt.wIndex = wInd;
|
||||
setup_pkt.wLength = total;
|
||||
|
||||
bytesWr(rSUDFIFO, 8, (uint8_t*) & setup_pkt); //transfer to setup packet FIFO
|
||||
bytesWr(rSUDFIFO, 8, (uint8_t*) & setup_pkt); // Transfer to setup packet FIFO
|
||||
|
||||
rcode = dispatchPkt(tokSETUP, ep, nak_limit); //dispatch packet
|
||||
rcode = dispatchPkt(tokSETUP, ep, nak_limit); // Dispatch packet
|
||||
if (rcode) return rcode; // Return HRSLT if not zero
|
||||
|
||||
if (dataptr != nullptr) { //data stage, if present
|
||||
if (direction) { //IN transfer
|
||||
if (dataptr) { // Data stage, if present
|
||||
if (direction) { // IN transfer
|
||||
uint16_t left = total;
|
||||
pep->bmRcvToggle = 1; //bmRCVTOG1;
|
||||
pep->bmRcvToggle = 1; // BmRCVTOG1;
|
||||
|
||||
while (left) {
|
||||
// Bytes read into buffer
|
||||
@@ -174,7 +171,7 @@ uint8_t USB::ctrlReq(uint8_t addr, uint8_t ep, uint8_t bmReqType, uint8_t bReque
|
||||
|
||||
rcode = InTransfer(pep, nak_limit, &read, dataptr);
|
||||
if (rcode == hrTOGERR) {
|
||||
// yes, we flip it wrong here so that next time it is actually correct!
|
||||
// Yes, we flip it wrong here so that next time it is actually correct!
|
||||
pep->bmRcvToggle = (regRd(rHRSL) & bmSNDTOGRD) ? 0 : 1;
|
||||
continue;
|
||||
}
|
||||
@@ -189,22 +186,22 @@ uint8_t USB::ctrlReq(uint8_t addr, uint8_t ep, uint8_t bmReqType, uint8_t bReque
|
||||
if (read < nbytes) break;
|
||||
}
|
||||
}
|
||||
else { //OUT transfer
|
||||
pep->bmSndToggle = 1; //bmSNDTOG1;
|
||||
else { // OUT transfer
|
||||
pep->bmSndToggle = 1; // BmSNDTOG1;
|
||||
rcode = OutTransfer(pep, nak_limit, nbytes, dataptr);
|
||||
}
|
||||
if (rcode) return rcode; // return error
|
||||
if (rcode) return rcode; // Return error
|
||||
}
|
||||
// Status stage
|
||||
return dispatchPkt((direction) ? tokOUTHS : tokINHS, ep, nak_limit); //GET if direction
|
||||
return dispatchPkt((direction) ? tokOUTHS : tokINHS, ep, nak_limit); // GET if direction
|
||||
}
|
||||
|
||||
/* IN transfer to arbitrary endpoint. Assumes PERADDR is set. Handles multiple packets if necessary. Transfers 'nbytes' bytes. */
|
||||
/* Keep sending INs and writes data to memory area pointed by 'data' */
|
||||
|
||||
/* rcode 0 if no errors. rcode 01-0f is relayed from dispatchPkt(). Rcode f0 means RCVDAVIRQ error,
|
||||
fe USB xfer timeout */
|
||||
uint8_t USB::inTransfer(uint8_t addr, uint8_t ep, uint16_t *nbytesptr, uint8_t* data, uint8_t bInterval /*= 0*/) {
|
||||
/**
|
||||
* IN transfer to arbitrary endpoint. Assumes PERADDR is set. Handles multiple packets if necessary. Transfers 'nbytes' bytes.
|
||||
* Keep sending INs and writes data to memory area pointed by 'data'
|
||||
* rcode 0 if no errors. rcode 01-0f is relayed from dispatchPkt(). Rcode f0 means RCVDAVIRQ error, fe = USB xfer timeout
|
||||
*/
|
||||
uint8_t USB::inTransfer(uint8_t addr, uint8_t ep, uint16_t *nbytesptr, uint8_t *data, uint8_t bInterval /*= 0*/) {
|
||||
EpInfo *pep = nullptr;
|
||||
uint16_t nak_limit = 0;
|
||||
|
||||
@@ -218,7 +215,7 @@ uint8_t USB::inTransfer(uint8_t addr, uint8_t ep, uint16_t *nbytesptr, uint8_t*
|
||||
return InTransfer(pep, nak_limit, nbytesptr, data, bInterval);
|
||||
}
|
||||
|
||||
uint8_t USB::InTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t *nbytesptr, uint8_t* data, uint8_t bInterval /*= 0*/) {
|
||||
uint8_t USB::InTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t *nbytesptr, uint8_t *data, uint8_t bInterval /*= 0*/) {
|
||||
uint8_t rcode = 0;
|
||||
uint8_t pktsize;
|
||||
|
||||
@@ -227,29 +224,29 @@ uint8_t USB::InTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t *nbytesptr, ui
|
||||
uint8_t maxpktsize = pep->maxPktSize;
|
||||
|
||||
*nbytesptr = 0;
|
||||
regWr(rHCTL, (pep->bmRcvToggle) ? bmRCVTOG1 : bmRCVTOG0); //set toggle value
|
||||
regWr(rHCTL, (pep->bmRcvToggle) ? bmRCVTOG1 : bmRCVTOG0); // Set toggle value
|
||||
|
||||
// use a 'break' to exit this loop
|
||||
// Use a 'break' to exit this loop
|
||||
for (;;) {
|
||||
rcode = dispatchPkt(tokIN, pep->epAddr, nak_limit); //IN packet to EP-'endpoint'. Function takes care of NAKS.
|
||||
rcode = dispatchPkt(tokIN, pep->epAddr, nak_limit); // IN packet to EP-'endpoint'. Function takes care of NAKS.
|
||||
if (rcode == hrTOGERR) {
|
||||
// yes, we flip it wrong here so that next time it is actually correct!
|
||||
// Yes, we flip it wrong here so that next time it is actually correct!
|
||||
pep->bmRcvToggle = (regRd(rHRSL) & bmRCVTOGRD) ? 0 : 1;
|
||||
regWr(rHCTL, (pep->bmRcvToggle) ? bmRCVTOG1 : bmRCVTOG0); //set toggle value
|
||||
regWr(rHCTL, (pep->bmRcvToggle) ? bmRCVTOG1 : bmRCVTOG0); // Set toggle value
|
||||
continue;
|
||||
}
|
||||
if (rcode) {
|
||||
//printf(">>>>>>>> Problem! dispatchPkt %2.2x\r\n", rcode);
|
||||
break; //should be 0, indicating ACK. Else return error code.
|
||||
break; // Should be 0, indicating ACK. Else return error code.
|
||||
}
|
||||
/* check for RCVDAVIRQ and generate error if not present */
|
||||
/* the only case when absence of RCVDAVIRQ makes sense is when toggle error occurred. Need to add handling for that */
|
||||
if ((regRd(rHIRQ) & bmRCVDAVIRQ) == 0) {
|
||||
//printf(">>>>>>>> Problem! NO RCVDAVIRQ!\r\n");
|
||||
rcode = 0xF0; //receive error
|
||||
rcode = 0xF0; // Receive error
|
||||
break;
|
||||
}
|
||||
pktsize = regRd(rRCVBC); //number of received bytes
|
||||
pktsize = regRd(rRCVBC); // Number of received bytes
|
||||
//printf("Got %i bytes \r\n", pktsize);
|
||||
// This would be OK, but...
|
||||
//assert(pktsize <= nbytes);
|
||||
@@ -266,7 +263,7 @@ uint8_t USB::InTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t *nbytesptr, ui
|
||||
data = bytesRd(rRCVFIFO, ((pktsize > mem_left) ? mem_left : pktsize), data);
|
||||
|
||||
regWr(rHIRQ, bmRCVDAVIRQ); // Clear the IRQ & free the buffer
|
||||
*nbytesptr += pktsize; // add this packet's byte count to total transfer length
|
||||
*nbytesptr += pktsize; // Add this packet's byte count to total transfer length
|
||||
|
||||
/* The transfer is complete under two conditions: */
|
||||
/* 1. The device sent a short packet (L.T. maxPacketSize) */
|
||||
@@ -284,11 +281,12 @@ uint8_t USB::InTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t *nbytesptr, ui
|
||||
return rcode;
|
||||
}
|
||||
|
||||
/* OUT transfer to arbitrary endpoint. Handles multiple packets if necessary. Transfers 'nbytes' bytes. */
|
||||
/* Handles NAK bug per Maxim Application Note 4000 for single buffer transfer */
|
||||
|
||||
/* rcode 0 if no errors. rcode 01-0f is relayed from HRSL */
|
||||
uint8_t USB::outTransfer(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t* data) {
|
||||
/**
|
||||
* OUT transfer to arbitrary endpoint. Handles multiple packets if necessary. Transfers 'nbytes' bytes.
|
||||
* Handles NAK bug per Maxim Application Note 4000 for single buffer transfer
|
||||
* rcode 0 if no errors. rcode 01-0f is relayed from HRSL
|
||||
*/
|
||||
uint8_t USB::outTransfer(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t *data) {
|
||||
EpInfo *pep = nullptr;
|
||||
uint16_t nak_limit = 0;
|
||||
|
||||
@@ -300,7 +298,7 @@ uint8_t USB::outTransfer(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t* dat
|
||||
|
||||
uint8_t USB::OutTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t nbytes, uint8_t *data) {
|
||||
uint8_t rcode = hrSUCCESS, retry_count;
|
||||
uint8_t *data_p = data; //local copy of the data pointer
|
||||
uint8_t *data_p = data; // Local copy of the data pointer
|
||||
uint16_t bytes_tosend, nak_count;
|
||||
uint16_t bytes_left = nbytes;
|
||||
|
||||
@@ -311,17 +309,17 @@ uint8_t USB::OutTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t nbytes, uint8
|
||||
|
||||
uint32_t timeout = (uint32_t)millis() + USB_XFER_TIMEOUT;
|
||||
|
||||
regWr(rHCTL, (pep->bmSndToggle) ? bmSNDTOG1 : bmSNDTOG0); //set toggle value
|
||||
regWr(rHCTL, (pep->bmSndToggle) ? bmSNDTOG1 : bmSNDTOG0); // Set toggle value
|
||||
|
||||
while (bytes_left) {
|
||||
retry_count = 0;
|
||||
nak_count = 0;
|
||||
bytes_tosend = (bytes_left >= maxpktsize) ? maxpktsize : bytes_left;
|
||||
bytesWr(rSNDFIFO, bytes_tosend, data_p); //filling output FIFO
|
||||
regWr(rSNDBC, bytes_tosend); //set number of bytes
|
||||
regWr(rHXFR, (tokOUT | pep->epAddr)); //dispatch packet
|
||||
while (!(regRd(rHIRQ) & bmHXFRDNIRQ)); //wait for the completion IRQ
|
||||
regWr(rHIRQ, bmHXFRDNIRQ); //clear IRQ
|
||||
bytesWr(rSNDFIFO, bytes_tosend, data_p); // Filling output FIFO
|
||||
regWr(rSNDBC, bytes_tosend); // Set number of bytes
|
||||
regWr(rHXFR, (tokOUT | pep->epAddr)); // Dispatch packet
|
||||
while (!(regRd(rHIRQ) & bmHXFRDNIRQ)); // Wait for the completion IRQ
|
||||
regWr(rHIRQ, bmHXFRDNIRQ); // Clear IRQ
|
||||
rcode = (regRd(rHRSL) & 0x0F);
|
||||
|
||||
while (rcode && ((int32_t)((uint32_t)millis() - timeout) < 0L)) {
|
||||
@@ -330,18 +328,18 @@ uint8_t USB::OutTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t nbytes, uint8
|
||||
nak_count++;
|
||||
if (nak_limit && (nak_count == nak_limit))
|
||||
goto breakout;
|
||||
//return ( rcode);
|
||||
//return rcode;
|
||||
break;
|
||||
case hrTIMEOUT:
|
||||
retry_count++;
|
||||
if (retry_count == USB_RETRY_LIMIT)
|
||||
goto breakout;
|
||||
//return ( rcode);
|
||||
//return rcode;
|
||||
break;
|
||||
case hrTOGERR:
|
||||
// yes, we flip it wrong here so that next time it is actually correct!
|
||||
// Yes, we flip it wrong here so that next time it is actually correct!
|
||||
pep->bmSndToggle = (regRd(rHRSL) & bmSNDTOGRD) ? 0 : 1;
|
||||
regWr(rHCTL, (pep->bmSndToggle) ? bmSNDTOG1 : bmSNDTOG0); //set toggle value
|
||||
regWr(rHCTL, (pep->bmSndToggle) ? bmSNDTOG1 : bmSNDTOG0); // Set toggle value
|
||||
break;
|
||||
default:
|
||||
goto breakout;
|
||||
@@ -351,26 +349,27 @@ uint8_t USB::OutTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t nbytes, uint8
|
||||
regWr(rSNDBC, 0);
|
||||
regWr(rSNDFIFO, *data_p);
|
||||
regWr(rSNDBC, bytes_tosend);
|
||||
regWr(rHXFR, (tokOUT | pep->epAddr)); //dispatch packet
|
||||
while (!(regRd(rHIRQ) & bmHXFRDNIRQ)); //wait for the completion IRQ
|
||||
regWr(rHIRQ, bmHXFRDNIRQ); //clear IRQ
|
||||
regWr(rHXFR, (tokOUT | pep->epAddr)); // Dispatch packet
|
||||
while (!(regRd(rHIRQ) & bmHXFRDNIRQ)); // Wait for the completion IRQ
|
||||
regWr(rHIRQ, bmHXFRDNIRQ); // Clear IRQ
|
||||
rcode = (regRd(rHRSL) & 0x0F);
|
||||
} // while rcode && ....
|
||||
} // While rcode && ....
|
||||
bytes_left -= bytes_tosend;
|
||||
data_p += bytes_tosend;
|
||||
} // while bytes_left...
|
||||
} // While bytes_left...
|
||||
breakout:
|
||||
|
||||
pep->bmSndToggle = (regRd(rHRSL) & bmSNDTOGRD) ? 1 : 0; //bmSNDTOG1 : bmSNDTOG0; //update toggle
|
||||
return ( rcode); //should be 0 in all cases
|
||||
pep->bmSndToggle = (regRd(rHRSL) & bmSNDTOGRD) ? 1 : 0; // BmSNDTOG1 : bmSNDTOG0; // Update toggle
|
||||
return ( rcode); // Should be 0 in all cases
|
||||
}
|
||||
|
||||
/* dispatch USB packet. Assumes peripheral address is set and relevant buffer is loaded/empty */
|
||||
/* If NAK, tries to re-send up to nak_limit times */
|
||||
/* If nak_limit == 0, do not count NAKs, exit after timeout */
|
||||
/* If bus timeout, re-sends up to USB_RETRY_LIMIT times */
|
||||
|
||||
/* return codes 0x00-0x0F are HRSLT( 0x00 being success ), 0xFF means timeout */
|
||||
/**
|
||||
* Dispatch USB packet. Assumes peripheral address is set and relevant buffer is loaded/empty
|
||||
* If NAK, tries to re-send up to nak_limit times
|
||||
* If nak_limit == 0, do not count NAKs, exit after timeout
|
||||
* If bus timeout, re-sends up to USB_RETRY_LIMIT times
|
||||
* return codes 0x00-0x0F are HRSLT( 0x00 being success ), 0xFF means timeout
|
||||
*/
|
||||
uint8_t USB::dispatchPkt(uint8_t token, uint8_t ep, uint16_t nak_limit) {
|
||||
uint32_t timeout = (uint32_t)millis() + USB_XFER_TIMEOUT;
|
||||
uint8_t tmpdata;
|
||||
@@ -380,29 +379,28 @@ uint8_t USB::dispatchPkt(uint8_t token, uint8_t ep, uint16_t nak_limit) {
|
||||
|
||||
while ((int32_t)((uint32_t)millis() - timeout) < 0L) {
|
||||
#if defined(ESP8266) || defined(ESP32)
|
||||
yield(); // needed in order to reset the watchdog timer on the ESP8266
|
||||
yield(); // Needed in order to reset the watchdog timer on the ESP8266
|
||||
#endif
|
||||
regWr(rHXFR, (token | ep)); //launch the transfer
|
||||
regWr(rHXFR, (token | ep)); // Launch the transfer
|
||||
rcode = USB_ERROR_TRANSFER_TIMEOUT;
|
||||
|
||||
while ((int32_t)((uint32_t)millis() - timeout) < 0L) { //wait for transfer completion
|
||||
while ((int32_t)((uint32_t)millis() - timeout) < 0L) { // Wait for transfer completion
|
||||
#if defined(ESP8266) || defined(ESP32)
|
||||
yield(); // needed to reset the watchdog timer on the ESP8266
|
||||
yield(); // Needed to reset the watchdog timer on the ESP8266
|
||||
#endif
|
||||
tmpdata = regRd(rHIRQ);
|
||||
|
||||
if (tmpdata & bmHXFRDNIRQ) {
|
||||
regWr(rHIRQ, bmHXFRDNIRQ); //clear the interrupt
|
||||
regWr(rHIRQ, bmHXFRDNIRQ); // Clear the interrupt
|
||||
rcode = 0x00;
|
||||
break;
|
||||
}
|
||||
|
||||
} // while millis() < timeout
|
||||
} // While millis() < timeout
|
||||
|
||||
//if (rcode != 0x00) //exit if timeout
|
||||
// return ( rcode);
|
||||
//if (rcode != 0x00) return rcode; // Exit if timeout
|
||||
|
||||
rcode = (regRd(rHRSL) & 0x0F); //analyze transfer result
|
||||
rcode = (regRd(rHRSL) & 0x0F); // Analyze transfer result
|
||||
|
||||
switch (rcode) {
|
||||
case hrNAK:
|
||||
@@ -419,16 +417,16 @@ uint8_t USB::dispatchPkt(uint8_t token, uint8_t ep, uint16_t nak_limit) {
|
||||
return (rcode);
|
||||
}
|
||||
|
||||
} // while timeout > millis()
|
||||
} // While timeout > millis()
|
||||
return rcode;
|
||||
}
|
||||
|
||||
/* USB main task. Performs enumeration/cleanup */
|
||||
void USB::Task() { //USB state machine
|
||||
// USB main task. Performs enumeration/cleanup
|
||||
void USB::Task() { // USB state machine
|
||||
uint8_t rcode;
|
||||
uint8_t tmpdata;
|
||||
static uint32_t delay = 0;
|
||||
//USB_DEVICE_DESCRIPTOR buf;
|
||||
//USB_FD_DEVICE_DESCRIPTOR buf;
|
||||
bool lowspeed = false;
|
||||
|
||||
MAX3421E::Task();
|
||||
@@ -437,19 +435,19 @@ void USB::Task() { //USB state machine
|
||||
|
||||
/* modify USB task state if Vbus changed */
|
||||
switch (tmpdata) {
|
||||
case SE1: //illegal state
|
||||
case SE1: // Illegal state
|
||||
usb_task_state = USB_DETACHED_SUBSTATE_ILLEGAL;
|
||||
lowspeed = false;
|
||||
break;
|
||||
case SE0: //disconnected
|
||||
case SE0: // Disconnected
|
||||
if ((usb_task_state & USB_STATE_MASK) != USB_STATE_DETACHED)
|
||||
usb_task_state = USB_DETACHED_SUBSTATE_INITIALIZE;
|
||||
lowspeed = false;
|
||||
break;
|
||||
case LSHOST:
|
||||
lowspeed = true;
|
||||
//intentional fallthrough
|
||||
case FSHOST: //attached
|
||||
// Intentional fallthrough
|
||||
case FSHOST: // Attached
|
||||
if ((usb_task_state & USB_STATE_MASK) == USB_STATE_DETACHED) {
|
||||
delay = (uint32_t)millis() + USB_SETTLE_DELAY;
|
||||
usb_task_state = USB_ATTACHED_SUBSTATE_SETTLE;
|
||||
@@ -470,31 +468,31 @@ void USB::Task() { //USB state machine
|
||||
|
||||
usb_task_state = USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE;
|
||||
break;
|
||||
case USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE: //just sit here
|
||||
case USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE: // Just sit here
|
||||
break;
|
||||
case USB_DETACHED_SUBSTATE_ILLEGAL: //just sit here
|
||||
case USB_DETACHED_SUBSTATE_ILLEGAL: // Just sit here
|
||||
break;
|
||||
case USB_ATTACHED_SUBSTATE_SETTLE: //settle time for just attached device
|
||||
case USB_ATTACHED_SUBSTATE_SETTLE: // Settle time for just attached device
|
||||
if ((int32_t)((uint32_t)millis() - delay) >= 0L)
|
||||
usb_task_state = USB_ATTACHED_SUBSTATE_RESET_DEVICE;
|
||||
else break; // don't fall through
|
||||
else break; // Don't fall through
|
||||
case USB_ATTACHED_SUBSTATE_RESET_DEVICE:
|
||||
regWr(rHCTL, bmBUSRST); //issue bus reset
|
||||
regWr(rHCTL, bmBUSRST); // Issue bus reset
|
||||
usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE;
|
||||
break;
|
||||
case USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE:
|
||||
if ((regRd(rHCTL) & bmBUSRST) == 0) {
|
||||
tmpdata = regRd(rMODE) | bmSOFKAENAB; //start SOF generation
|
||||
tmpdata = regRd(rMODE) | bmSOFKAENAB; // Start SOF generation
|
||||
regWr(rMODE, tmpdata);
|
||||
usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_SOF;
|
||||
//delay = (uint32_t)millis() + 20; //20ms wait after reset per USB spec
|
||||
//delay = (uint32_t)millis() + 20; // 20ms wait after reset per USB spec
|
||||
}
|
||||
break;
|
||||
case USB_ATTACHED_SUBSTATE_WAIT_SOF: //todo: change check order
|
||||
case USB_ATTACHED_SUBSTATE_WAIT_SOF: // Todo: change check order
|
||||
if (regRd(rHIRQ) & bmFRAMEIRQ) {
|
||||
//when first SOF received _and_ 20ms has passed we can continue
|
||||
// When first SOF received _and_ 20ms has passed we can continue
|
||||
/*
|
||||
if (delay < (uint32_t)millis()) //20ms passed
|
||||
if (delay < (uint32_t)millis()) // 20ms passed
|
||||
usb_task_state = USB_STATE_CONFIGURING;
|
||||
*/
|
||||
usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_RESET;
|
||||
@@ -503,7 +501,7 @@ void USB::Task() { //USB state machine
|
||||
break;
|
||||
case USB_ATTACHED_SUBSTATE_WAIT_RESET:
|
||||
if ((int32_t)((uint32_t)millis() - delay) >= 0L) usb_task_state = USB_STATE_CONFIGURING;
|
||||
else break; // don't fall through
|
||||
else break; // Don't fall through
|
||||
case USB_STATE_CONFIGURING:
|
||||
|
||||
//Serial.print("\r\nConf.LS: ");
|
||||
@@ -565,11 +563,11 @@ again:
|
||||
if (rcode == USB_ERROR_CONFIG_REQUIRES_ADDITIONAL_RESET) {
|
||||
if (parent == 0) {
|
||||
// Send a bus reset on the root interface.
|
||||
regWr(rHCTL, bmBUSRST); //issue bus reset
|
||||
delay(102); // delay 102ms, compensate for clock inaccuracy.
|
||||
regWr(rHCTL, bmBUSRST); // Issue bus reset
|
||||
delay(102); // Delay 102ms, compensate for clock inaccuracy.
|
||||
}
|
||||
else {
|
||||
// reset parent port
|
||||
// Reset parent port
|
||||
devConfig[parent]->ResetHubPort(port);
|
||||
}
|
||||
}
|
||||
@@ -592,11 +590,11 @@ again:
|
||||
// Issue a bus reset, because the device may be in a limbo state
|
||||
if (parent == 0) {
|
||||
// Send a bus reset on the root interface.
|
||||
regWr(rHCTL, bmBUSRST); //issue bus reset
|
||||
delay(102); // delay 102ms, compensate for clock inaccuracy.
|
||||
regWr(rHCTL, bmBUSRST); // Issue bus reset
|
||||
delay(102); // Delay 102ms, compensate for clock inaccuracy.
|
||||
}
|
||||
else {
|
||||
// reset parent port
|
||||
// Reset parent port
|
||||
devConfig[parent]->ResetHubPort(port);
|
||||
}
|
||||
}
|
||||
@@ -623,32 +621,31 @@ again:
|
||||
* 4: set address
|
||||
* 5: pUsb->setEpInfoEntry(bAddress, 1, epInfo), exit on fail
|
||||
* 6: while (configurations) {
|
||||
* for (each configuration) {
|
||||
* for (each driver) {
|
||||
* 6a: Ask device if it likes configuration. Returns 0 on OK.
|
||||
* If successful, the driver configured device.
|
||||
* The driver now owns the endpoints, and takes over managing them.
|
||||
* The following will need codes:
|
||||
* Everything went well, instance consumed, exit with success.
|
||||
* Instance already in use, ignore it, try next driver.
|
||||
* Not a supported device, ignore it, try next driver.
|
||||
* Not a supported configuration for this device, ignore it, try next driver.
|
||||
* Could not configure device, fatal, exit with fail.
|
||||
* }
|
||||
* }
|
||||
* for (each configuration) {
|
||||
* for (each driver) {
|
||||
* 6a: Ask device if it likes configuration. Returns 0 on OK.
|
||||
* If successful, the driver configured device.
|
||||
* The driver now owns the endpoints, and takes over managing them.
|
||||
* The following will need codes:
|
||||
* Everything went well, instance consumed, exit with success.
|
||||
* Instance already in use, ignore it, try next driver.
|
||||
* Not a supported device, ignore it, try next driver.
|
||||
* Not a supported configuration for this device, ignore it, try next driver.
|
||||
* Could not configure device, fatal, exit with fail.
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* 7: for (each driver) {
|
||||
* 7a: Ask device if it knows this VID/PID. Acts exactly like 6a, but using VID/PID
|
||||
* 8: if we get here, no driver likes the device plugged in, so exit failure.
|
||||
*
|
||||
*/
|
||||
uint8_t USB::Configuring(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||
//uint8_t bAddress = 0;
|
||||
//printf("Configuring: parent = %i, port = %i\r\n", parent, port);
|
||||
uint8_t devConfigIndex;
|
||||
uint8_t rcode = 0;
|
||||
uint8_t buf[sizeof (USB_DEVICE_DESCRIPTOR)];
|
||||
USB_DEVICE_DESCRIPTOR *udd = reinterpret_cast<USB_DEVICE_DESCRIPTOR *>(buf);
|
||||
uint8_t buf[sizeof (USB_FD_DEVICE_DESCRIPTOR)];
|
||||
USB_FD_DEVICE_DESCRIPTOR *udd = reinterpret_cast<USB_FD_DEVICE_DESCRIPTOR *>(buf);
|
||||
UsbDevice *p = nullptr;
|
||||
EpInfo *oldep_ptr = nullptr;
|
||||
EpInfo epInfo;
|
||||
@@ -672,23 +669,23 @@ uint8_t USB::Configuring(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||
oldep_ptr = p->epinfo;
|
||||
|
||||
// Temporary assign new pointer to epInfo to p->epinfo in order to
|
||||
// avoid toggle inconsistence
|
||||
// Avoid toggle inconsistence
|
||||
|
||||
p->epinfo = &epInfo;
|
||||
|
||||
p->lowspeed = lowspeed;
|
||||
// Get device descriptor
|
||||
rcode = getDevDescr(0, 0, sizeof (USB_DEVICE_DESCRIPTOR), (uint8_t*)buf);
|
||||
rcode = getDevDescr(0, 0, sizeof (USB_FD_DEVICE_DESCRIPTOR), (uint8_t*)buf);
|
||||
|
||||
// Restore p->epinfo
|
||||
p->epinfo = oldep_ptr;
|
||||
|
||||
if (rcode) {
|
||||
//printf("Configuring error: Can't get USB_DEVICE_DESCRIPTOR\r\n");
|
||||
//printf("Configuring error: Can't get USB_FD_DEVICE_DESCRIPTOR\r\n");
|
||||
return rcode;
|
||||
}
|
||||
|
||||
// to-do?
|
||||
// To-do?
|
||||
// Allocate new address according to device class
|
||||
//bAddress = addrPool.AllocAddress(parent, false, port);
|
||||
|
||||
@@ -699,11 +696,11 @@ uint8_t USB::Configuring(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||
// Qualify with subclass too.
|
||||
//
|
||||
// VID/PID & class tests default to false for drivers not yet ported
|
||||
// subclass defaults to true, so you don't have to define it if you don't have to.
|
||||
// Subclass defaults to true, so you don't have to define it if you don't have to.
|
||||
//
|
||||
for (devConfigIndex = 0; devConfigIndex < USB_NUMDEVICES; devConfigIndex++) {
|
||||
if (!devConfig[devConfigIndex]) continue; // no driver
|
||||
if (devConfig[devConfigIndex]->GetAddress()) continue; // consumed
|
||||
if (!devConfig[devConfigIndex]) continue; // No driver
|
||||
if (devConfig[devConfigIndex]->GetAddress()) continue; // Consumed
|
||||
if (devConfig[devConfigIndex]->DEVSUBCLASSOK(subklass) && (devConfig[devConfigIndex]->VIDPIDOK(vid, pid) || devConfig[devConfigIndex]->DEVCLASSOK(klass))) {
|
||||
rcode = AttemptConfig(devConfigIndex, parent, port, lowspeed);
|
||||
if (rcode != USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED)
|
||||
@@ -713,20 +710,20 @@ uint8_t USB::Configuring(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||
|
||||
if (devConfigIndex < USB_NUMDEVICES) return rcode;
|
||||
|
||||
// blindly attempt to configure
|
||||
// Blindly attempt to configure
|
||||
for (devConfigIndex = 0; devConfigIndex < USB_NUMDEVICES; devConfigIndex++) {
|
||||
if (!devConfig[devConfigIndex]) continue;
|
||||
if (devConfig[devConfigIndex]->GetAddress()) continue; // consumed
|
||||
if (devConfig[devConfigIndex]->GetAddress()) continue; // Consumed
|
||||
if (devConfig[devConfigIndex]->DEVSUBCLASSOK(subklass) && (devConfig[devConfigIndex]->VIDPIDOK(vid, pid) || devConfig[devConfigIndex]->DEVCLASSOK(klass))) continue; // If this is true it means it must have returned USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED above
|
||||
rcode = AttemptConfig(devConfigIndex, parent, port, lowspeed);
|
||||
|
||||
//printf("ERROR ENUMERATING %2.2x\r\n", rcode);
|
||||
if (!(rcode == USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED || rcode == USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE)) {
|
||||
// in case of an error dev_index should be reset to 0
|
||||
// in order to start from the very beginning the
|
||||
// next time the program gets here
|
||||
// In case of an error dev_index should be reset to 0
|
||||
// in order to start from the very beginning the
|
||||
// next time the program gets here
|
||||
//if (rcode != USB_DEV_CONFIG_ERROR_DEVICE_INIT_INCOMPLETE)
|
||||
// devConfigIndex = 0;
|
||||
//devConfigIndex = 0;
|
||||
return rcode;
|
||||
}
|
||||
}
|
||||
@@ -745,24 +742,26 @@ uint8_t USB::ReleaseDevice(uint8_t addr) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 1 //!defined(USB_METHODS_INLINE)
|
||||
//get device descriptor
|
||||
|
||||
uint8_t USB::getDevDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t* dataptr) {
|
||||
// Get device descriptor
|
||||
uint8_t USB::getDevDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t *dataptr) {
|
||||
return ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, 0x00, USB_DESCRIPTOR_DEVICE, 0x0000, nbytes, nbytes, dataptr, nullptr);
|
||||
}
|
||||
//get configuration descriptor
|
||||
|
||||
uint8_t USB::getConfDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t conf, uint8_t* dataptr) {
|
||||
// Get configuration descriptor
|
||||
uint8_t USB::getConfDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t conf, uint8_t *dataptr) {
|
||||
return ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, conf, USB_DESCRIPTOR_CONFIGURATION, 0x0000, nbytes, nbytes, dataptr, nullptr);
|
||||
}
|
||||
|
||||
/* Requests Configuration Descriptor. Sends two Get Conf Descr requests. The first one gets the total length of all descriptors, then the second one requests this
|
||||
total length. The length of the first request can be shorter ( 4 bytes ), however, there are devices which won't work unless this length is set to 9 */
|
||||
/**
|
||||
* Requests Configuration Descriptor. Sends two Get Conf Descr requests.
|
||||
* The first one gets the total length of all descriptors, then the second one requests this
|
||||
* total length. The length of the first request can be shorter (4 bytes), however, there are
|
||||
* devices which won't work unless this length is set to 9.
|
||||
*/
|
||||
uint8_t USB::getConfDescr(uint8_t addr, uint8_t ep, uint8_t conf, USBReadParser *p) {
|
||||
const uint8_t bufSize = 64;
|
||||
uint8_t buf[bufSize];
|
||||
USB_CONFIGURATION_DESCRIPTOR *ucd = reinterpret_cast<USB_CONFIGURATION_DESCRIPTOR *>(buf);
|
||||
USB_FD_CONFIGURATION_DESCRIPTOR *ucd = reinterpret_cast<USB_FD_CONFIGURATION_DESCRIPTOR *>(buf);
|
||||
|
||||
uint8_t ret = getConfDescr(addr, ep, 9, conf, buf);
|
||||
if (ret) return ret;
|
||||
@@ -774,25 +773,23 @@ uint8_t USB::getConfDescr(uint8_t addr, uint8_t ep, uint8_t conf, USBReadParser
|
||||
return ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, conf, USB_DESCRIPTOR_CONFIGURATION, 0x0000, total, bufSize, buf, p);
|
||||
}
|
||||
|
||||
//get string descriptor
|
||||
|
||||
uint8_t USB::getStrDescr(uint8_t addr, uint8_t ep, uint16_t ns, uint8_t index, uint16_t langid, uint8_t* dataptr) {
|
||||
// Get string descriptor
|
||||
uint8_t USB::getStrDescr(uint8_t addr, uint8_t ep, uint16_t ns, uint8_t index, uint16_t langid, uint8_t *dataptr) {
|
||||
return ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, index, USB_DESCRIPTOR_STRING, langid, ns, ns, dataptr, nullptr);
|
||||
}
|
||||
//set address
|
||||
|
||||
// Set address
|
||||
uint8_t USB::setAddr(uint8_t oldaddr, uint8_t ep, uint8_t newaddr) {
|
||||
uint8_t rcode = ctrlReq(oldaddr, ep, bmREQ_SET, USB_REQUEST_SET_ADDRESS, newaddr, 0x00, 0x0000, 0x0000, 0x0000, nullptr, nullptr);
|
||||
//delay(2); //per USB 2.0 sect.9.2.6.3
|
||||
//delay(2); // Per USB 2.0 sect.9.2.6.3
|
||||
delay(300); // Older spec says you should wait at least 200ms
|
||||
return rcode;
|
||||
//return ctrlReq(oldaddr, ep, bmREQ_SET, USB_REQUEST_SET_ADDRESS, newaddr, 0x00, 0x0000, 0x0000, 0x0000, nullptr, nullptr);
|
||||
}
|
||||
//set configuration
|
||||
|
||||
// Set configuration
|
||||
uint8_t USB::setConf(uint8_t addr, uint8_t ep, uint8_t conf_value) {
|
||||
return ctrlReq(addr, ep, bmREQ_SET, USB_REQUEST_SET_CONFIGURATION, conf_value, 0x00, 0x0000, 0x0000, 0x0000, nullptr, nullptr);
|
||||
}
|
||||
|
||||
#endif // defined(USB_METHODS_INLINE)
|
||||
#endif // USB_FLASH_DRIVE_SUPPORT
|
||||
|
2
Marlin/src/sd/usb_flashdrive/lib-uhs2/Usb.h
Executable file → Normal file
2
Marlin/src/sd/usb_flashdrive/lib-uhs2/Usb.h
Executable file → Normal file
@@ -19,7 +19,7 @@
|
||||
* -------------------
|
||||
*
|
||||
* Circuits At Home, LTD
|
||||
* Web : http://www.circuitsathome.com
|
||||
* Web : https://www.circuitsathome.com
|
||||
* e-mail : support@circuitsathome.com
|
||||
*/
|
||||
#pragma once
|
||||
|
48
Marlin/src/sd/usb_flashdrive/lib-uhs2/UsbCore.h
Executable file → Normal file
48
Marlin/src/sd/usb_flashdrive/lib-uhs2/UsbCore.h
Executable file → Normal file
@@ -19,7 +19,7 @@
|
||||
* -------------------
|
||||
*
|
||||
* Circuits At Home, LTD
|
||||
* Web : http://www.circuitsathome.com
|
||||
* Web : https://www.circuitsathome.com
|
||||
* e-mail : support@circuitsathome.com
|
||||
*/
|
||||
|
||||
@@ -78,16 +78,16 @@ typedef MAX3421e<P10, P9> MAX3421E; // Official Arduinos (UNO, Duemilanove, Mega
|
||||
#define USB_CLASS_PRINTER 0x07 // Printer
|
||||
#define USB_CLASS_MASS_STORAGE 0x08 // Mass Storage
|
||||
#define USB_CLASS_HUB 0x09 // Hub
|
||||
#define USB_CLASS_CDC_DATA 0x0a // CDC-Data
|
||||
#define USB_CLASS_SMART_CARD 0x0b // Smart-Card
|
||||
#define USB_CLASS_CONTENT_SECURITY 0x0d // Content Security
|
||||
#define USB_CLASS_VIDEO 0x0e // Video
|
||||
#define USB_CLASS_PERSONAL_HEALTH 0x0f // Personal Healthcare
|
||||
#define USB_CLASS_DIAGNOSTIC_DEVICE 0xdc // Diagnostic Device
|
||||
#define USB_CLASS_WIRELESS_CTRL 0xe0 // Wireless Controller
|
||||
#define USB_CLASS_MISC 0xef // Miscellaneous
|
||||
#define USB_CLASS_APP_SPECIFIC 0xfe // Application Specific
|
||||
#define USB_CLASS_VENDOR_SPECIFIC 0xff // Vendor Specific
|
||||
#define USB_CLASS_CDC_DATA 0x0A // CDC-Data
|
||||
#define USB_CLASS_SMART_CARD 0x0B // Smart-Card
|
||||
#define USB_CLASS_CONTENT_SECURITY 0x0D // Content Security
|
||||
#define USB_CLASS_VIDEO 0x0E // Video
|
||||
#define USB_CLASS_PERSONAL_HEALTH 0x0F // Personal Healthcare
|
||||
#define USB_CLASS_DIAGNOSTIC_DEVICE 0xDC // Diagnostic Device
|
||||
#define USB_CLASS_WIRELESS_CTRL 0xE0 // Wireless Controller
|
||||
#define USB_CLASS_MISC 0xEF // Miscellaneous
|
||||
#define USB_CLASS_APP_SPECIFIC 0xFE // Application Specific
|
||||
#define USB_CLASS_VENDOR_SPECIFIC 0xFF // Vendor Specific
|
||||
|
||||
// Additional Error Codes
|
||||
#define USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED 0xD1
|
||||
@@ -114,10 +114,10 @@ typedef MAX3421e<P10, P9> MAX3421E; // Official Arduinos (UNO, Duemilanove, Mega
|
||||
|
||||
#define USB_NUMDEVICES 16 //number of USB devices
|
||||
//#define HUB_MAX_HUBS 7 // maximum number of hubs that can be attached to the host controller
|
||||
#define HUB_PORT_RESET_DELAY 20 // hub port reset delay 10 ms recomended, can be up to 20 ms
|
||||
#define HUB_PORT_RESET_DELAY 20 // hub port reset delay 10 ms recommended, can be up to 20 ms
|
||||
|
||||
/* USB state machine states */
|
||||
#define USB_STATE_MASK 0xf0
|
||||
#define USB_STATE_MASK 0xF0
|
||||
|
||||
#define USB_STATE_DETACHED 0x10
|
||||
#define USB_DETACHED_SUBSTATE_INITIALIZE 0x11
|
||||
@@ -132,7 +132,7 @@ typedef MAX3421e<P10, P9> MAX3421E; // Official Arduinos (UNO, Duemilanove, Mega
|
||||
#define USB_STATE_ADDRESSING 0x70
|
||||
#define USB_STATE_CONFIGURING 0x80
|
||||
#define USB_STATE_RUNNING 0x90
|
||||
#define USB_STATE_ERROR 0xa0
|
||||
#define USB_STATE_ERROR 0xA0
|
||||
|
||||
class USBDeviceConfig {
|
||||
public:
|
||||
@@ -250,19 +250,19 @@ public:
|
||||
uint8_t setEpInfoEntry(uint8_t addr, uint8_t epcount, EpInfo* eprecord_ptr);
|
||||
|
||||
/* Control requests */
|
||||
uint8_t getDevDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t* dataptr);
|
||||
uint8_t getConfDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t conf, uint8_t* dataptr);
|
||||
uint8_t getDevDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t *dataptr);
|
||||
uint8_t getConfDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t conf, uint8_t *dataptr);
|
||||
|
||||
uint8_t getConfDescr(uint8_t addr, uint8_t ep, uint8_t conf, USBReadParser *p);
|
||||
|
||||
uint8_t getStrDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t index, uint16_t langid, uint8_t* dataptr);
|
||||
uint8_t getStrDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t index, uint16_t langid, uint8_t *dataptr);
|
||||
uint8_t setAddr(uint8_t oldaddr, uint8_t ep, uint8_t newaddr);
|
||||
uint8_t setConf(uint8_t addr, uint8_t ep, uint8_t conf_value);
|
||||
/**/
|
||||
uint8_t ctrlData(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t* dataptr, bool direction);
|
||||
uint8_t ctrlData(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t *dataptr, bool direction);
|
||||
uint8_t ctrlStatus(uint8_t ep, bool direction, uint16_t nak_limit);
|
||||
uint8_t inTransfer(uint8_t addr, uint8_t ep, uint16_t *nbytesptr, uint8_t* data, uint8_t bInterval = 0);
|
||||
uint8_t outTransfer(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t* data);
|
||||
uint8_t inTransfer(uint8_t addr, uint8_t ep, uint16_t *nbytesptr, uint8_t *data, uint8_t bInterval = 0);
|
||||
uint8_t outTransfer(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t *data);
|
||||
uint8_t dispatchPkt(uint8_t token, uint8_t ep, uint16_t nak_limit);
|
||||
|
||||
void Task();
|
||||
@@ -272,7 +272,7 @@ public:
|
||||
uint8_t ReleaseDevice(uint8_t addr);
|
||||
|
||||
uint8_t ctrlReq(uint8_t addr, uint8_t ep, uint8_t bmReqType, uint8_t bRequest, uint8_t wValLo, uint8_t wValHi,
|
||||
uint16_t wInd, uint16_t total, uint16_t nbytes, uint8_t* dataptr, USBReadParser *p);
|
||||
uint16_t wInd, uint16_t total, uint16_t nbytes, uint8_t *dataptr, USBReadParser *p);
|
||||
|
||||
private:
|
||||
void init();
|
||||
@@ -285,17 +285,17 @@ private:
|
||||
#if 0 //defined(USB_METHODS_INLINE)
|
||||
//get device descriptor
|
||||
|
||||
inline uint8_t USB::getDevDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t* dataptr) {
|
||||
inline uint8_t USB::getDevDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t *dataptr) {
|
||||
return ( ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, 0x00, USB_DESCRIPTOR_DEVICE, 0x0000, nbytes, dataptr));
|
||||
}
|
||||
//get configuration descriptor
|
||||
|
||||
inline uint8_t USB::getConfDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t conf, uint8_t* dataptr) {
|
||||
inline uint8_t USB::getConfDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t conf, uint8_t *dataptr) {
|
||||
return ( ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, conf, USB_DESCRIPTOR_CONFIGURATION, 0x0000, nbytes, dataptr));
|
||||
}
|
||||
//get string descriptor
|
||||
|
||||
inline uint8_t USB::getStrDescr(uint8_t addr, uint8_t ep, uint16_t nuint8_ts, uint8_t index, uint16_t langid, uint8_t* dataptr) {
|
||||
inline uint8_t USB::getStrDescr(uint8_t addr, uint8_t ep, uint16_t nuint8_ts, uint8_t index, uint16_t langid, uint8_t *dataptr) {
|
||||
return ( ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, index, USB_DESCRIPTOR_STRING, langid, nuint8_ts, dataptr));
|
||||
}
|
||||
//set address
|
||||
|
2
Marlin/src/sd/usb_flashdrive/lib-uhs2/address.h
Executable file → Normal file
2
Marlin/src/sd/usb_flashdrive/lib-uhs2/address.h
Executable file → Normal file
@@ -19,7 +19,7 @@
|
||||
* -------------------
|
||||
*
|
||||
* Circuits At Home, LTD
|
||||
* Web : http://www.circuitsathome.com
|
||||
* Web : https://www.circuitsathome.com
|
||||
* e-mail : support@circuitsathome.com
|
||||
*/
|
||||
#pragma once
|
||||
|
18
Marlin/src/sd/usb_flashdrive/lib-uhs2/confdescparser.h
Executable file → Normal file
18
Marlin/src/sd/usb_flashdrive/lib-uhs2/confdescparser.h
Executable file → Normal file
@@ -19,7 +19,7 @@
|
||||
* -------------------
|
||||
*
|
||||
* Circuits At Home, LTD
|
||||
* Web : http://www.circuitsathome.com
|
||||
* Web : https://www.circuitsathome.com
|
||||
* e-mail : support@circuitsathome.com
|
||||
*/
|
||||
#pragma once
|
||||
@@ -30,10 +30,10 @@
|
||||
|
||||
class UsbConfigXtracter {
|
||||
public:
|
||||
//virtual void ConfigXtract(const USB_CONFIGURATION_DESCRIPTOR *conf) = 0;
|
||||
//virtual void InterfaceXtract(uint8_t conf, const USB_INTERFACE_DESCRIPTOR *iface) = 0;
|
||||
//virtual void ConfigXtract(const USB_FD_CONFIGURATION_DESCRIPTOR *conf) = 0;
|
||||
//virtual void InterfaceXtract(uint8_t conf, const USB_FD_INTERFACE_DESCRIPTOR *iface) = 0;
|
||||
|
||||
virtual void EndpointXtract(uint8_t conf __attribute__((unused)), uint8_t iface __attribute__((unused)), uint8_t alt __attribute__((unused)), uint8_t proto __attribute__((unused)), const USB_ENDPOINT_DESCRIPTOR *ep __attribute__((unused))) {
|
||||
virtual void EndpointXtract(uint8_t conf __attribute__((unused)), uint8_t iface __attribute__((unused)), uint8_t alt __attribute__((unused)), uint8_t proto __attribute__((unused)), const USB_FD_ENDPOINT_DESCRIPTOR *ep __attribute__((unused))) {
|
||||
}
|
||||
};
|
||||
|
||||
@@ -50,14 +50,14 @@ class ConfigDescParser : public USBReadParser {
|
||||
MultiValueBuffer theBuffer;
|
||||
MultiByteValueParser valParser;
|
||||
ByteSkipper theSkipper;
|
||||
uint8_t varBuffer[16 /*sizeof(USB_CONFIGURATION_DESCRIPTOR)*/];
|
||||
uint8_t varBuffer[16 /*sizeof(USB_FD_CONFIGURATION_DESCRIPTOR)*/];
|
||||
|
||||
uint8_t stateParseDescr; // ParseDescriptor state
|
||||
|
||||
uint8_t dscrLen; // Descriptor length
|
||||
uint8_t dscrType; // Descriptor type
|
||||
|
||||
bool isGoodInterface; // Apropriate interface flag
|
||||
bool isGoodInterface; // Appropriate interface flag
|
||||
uint8_t confValue; // Configuration value
|
||||
uint8_t protoValue; // Protocol value
|
||||
uint8_t ifaceNumber; // Interface number
|
||||
@@ -97,8 +97,8 @@ void ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::Parse(const uin
|
||||
compare masks for them. When the match is found, calls EndpointXtract passing buffer containing endpoint descriptor */
|
||||
template <const uint8_t CLASS_ID, const uint8_t SUBCLASS_ID, const uint8_t PROTOCOL_ID, const uint8_t MASK>
|
||||
bool ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::ParseDescriptor(uint8_t **pp, uint16_t *pcntdn) {
|
||||
USB_CONFIGURATION_DESCRIPTOR* ucd = reinterpret_cast<USB_CONFIGURATION_DESCRIPTOR*>(varBuffer);
|
||||
USB_INTERFACE_DESCRIPTOR* uid = reinterpret_cast<USB_INTERFACE_DESCRIPTOR*>(varBuffer);
|
||||
USB_FD_CONFIGURATION_DESCRIPTOR* ucd = reinterpret_cast<USB_FD_CONFIGURATION_DESCRIPTOR*>(varBuffer);
|
||||
USB_FD_INTERFACE_DESCRIPTOR* uid = reinterpret_cast<USB_FD_INTERFACE_DESCRIPTOR*>(varBuffer);
|
||||
switch (stateParseDescr) {
|
||||
case 0:
|
||||
theBuffer.valueSize = 2;
|
||||
@@ -155,7 +155,7 @@ bool ConfigDescParser<CLASS_ID, SUBCLASS_ID, PROTOCOL_ID, MASK>::ParseDescriptor
|
||||
case USB_DESCRIPTOR_ENDPOINT:
|
||||
if (!valParser.Parse(pp, pcntdn)) return false;
|
||||
if (isGoodInterface && theXtractor)
|
||||
theXtractor->EndpointXtract(confValue, ifaceNumber, ifaceAltSet, protoValue, (USB_ENDPOINT_DESCRIPTOR*)varBuffer);
|
||||
theXtractor->EndpointXtract(confValue, ifaceNumber, ifaceAltSet, protoValue, (USB_FD_ENDPOINT_DESCRIPTOR*)varBuffer);
|
||||
break;
|
||||
//case HID_DESCRIPTOR_HID:
|
||||
// if (!valParser.Parse(pp, pcntdn)) return false;
|
||||
|
2
Marlin/src/sd/usb_flashdrive/lib-uhs2/hexdump.h
Executable file → Normal file
2
Marlin/src/sd/usb_flashdrive/lib-uhs2/hexdump.h
Executable file → Normal file
@@ -19,7 +19,7 @@
|
||||
* -------------------
|
||||
*
|
||||
* Circuits At Home, LTD
|
||||
* Web : http://www.circuitsathome.com
|
||||
* Web : https://www.circuitsathome.com
|
||||
* e-mail : support@circuitsathome.com
|
||||
*/
|
||||
#pragma once
|
||||
|
20
Marlin/src/sd/usb_flashdrive/lib-uhs2/macros.h
Executable file → Normal file
20
Marlin/src/sd/usb_flashdrive/lib-uhs2/macros.h
Executable file → Normal file
@@ -19,7 +19,7 @@
|
||||
* -------------------
|
||||
*
|
||||
* Circuits At Home, LTD
|
||||
* Web : http://www.circuitsathome.com
|
||||
* Web : https://www.circuitsathome.com
|
||||
* e-mail : support@circuitsathome.com
|
||||
*/
|
||||
#pragma once
|
||||
@@ -52,16 +52,16 @@
|
||||
#define BGRAB7(__usi__) (((uint8_t *)&(__usi__))[7])
|
||||
#else
|
||||
// Note: The cast alone to uint8_t is actually enough.
|
||||
// GCC throws out the "& 0xff", and the size is no different.
|
||||
// GCC throws out the "& 0xFF", and the size is no different.
|
||||
// Some compilers need it.
|
||||
#define BGRAB0(__usi__) ((uint8_t)((__usi__) & 0xff ))
|
||||
#define BGRAB1(__usi__) ((uint8_t)(((__usi__) >> 8) & 0xff))
|
||||
#define BGRAB2(__usi__) ((uint8_t)(((__usi__) >> 16) & 0xff))
|
||||
#define BGRAB3(__usi__) ((uint8_t)(((__usi__) >> 24) & 0xff))
|
||||
#define BGRAB4(__usi__) ((uint8_t)(((__usi__) >> 32) & 0xff))
|
||||
#define BGRAB5(__usi__) ((uint8_t)(((__usi__) >> 40) & 0xff))
|
||||
#define BGRAB6(__usi__) ((uint8_t)(((__usi__) >> 48) & 0xff))
|
||||
#define BGRAB7(__usi__) ((uint8_t)(((__usi__) >> 56) & 0xff))
|
||||
#define BGRAB0(__usi__) ((uint8_t)((__usi__) & 0xFF ))
|
||||
#define BGRAB1(__usi__) ((uint8_t)(((__usi__) >> 8) & 0xFF))
|
||||
#define BGRAB2(__usi__) ((uint8_t)(((__usi__) >> 16) & 0xFF))
|
||||
#define BGRAB3(__usi__) ((uint8_t)(((__usi__) >> 24) & 0xFF))
|
||||
#define BGRAB4(__usi__) ((uint8_t)(((__usi__) >> 32) & 0xFF))
|
||||
#define BGRAB5(__usi__) ((uint8_t)(((__usi__) >> 40) & 0xFF))
|
||||
#define BGRAB6(__usi__) ((uint8_t)(((__usi__) >> 48) & 0xFF))
|
||||
#define BGRAB7(__usi__) ((uint8_t)(((__usi__) >> 56) & 0xFF))
|
||||
#endif
|
||||
#define BOVER1(__usi__) ((uint16_t)(__usi__) << 8)
|
||||
#define BOVER2(__usi__) ((uint32_t)(__usi__) << 16)
|
||||
|
34
Marlin/src/sd/usb_flashdrive/lib-uhs2/masstorage.cpp
Executable file → Normal file
34
Marlin/src/sd/usb_flashdrive/lib-uhs2/masstorage.cpp
Executable file → Normal file
@@ -19,7 +19,7 @@
|
||||
* -------------------
|
||||
*
|
||||
* Circuits At Home, LTD
|
||||
* Web : http://www.circuitsathome.com
|
||||
* Web : https://www.circuitsathome.com
|
||||
* e-mail : support@circuitsathome.com
|
||||
*/
|
||||
|
||||
@@ -250,10 +250,10 @@ bLastUsbError(0) {
|
||||
*/
|
||||
uint8_t BulkOnly::ConfigureDevice(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||
|
||||
const uint8_t constBufSize = sizeof (USB_DEVICE_DESCRIPTOR);
|
||||
const uint8_t constBufSize = sizeof (USB_FD_DEVICE_DESCRIPTOR);
|
||||
|
||||
uint8_t buf[constBufSize];
|
||||
USB_DEVICE_DESCRIPTOR * udd = reinterpret_cast<USB_DEVICE_DESCRIPTOR*>(buf);
|
||||
USB_FD_DEVICE_DESCRIPTOR * udd = reinterpret_cast<USB_FD_DEVICE_DESCRIPTOR*>(buf);
|
||||
uint8_t rcode;
|
||||
UsbDevice *p = nullptr;
|
||||
EpInfo *oldep_ptr = nullptr;
|
||||
@@ -439,7 +439,7 @@ uint8_t BulkOnly::Init(uint8_t parent __attribute__((unused)), uint8_t port __at
|
||||
printf(" standards.\r\n");
|
||||
#endif
|
||||
|
||||
uint8_t tries = 0xf0;
|
||||
uint8_t tries = 0xF0;
|
||||
while ((rcode = TestUnitReady(lun))) {
|
||||
if (rcode == 0x08) break; // break on no media, this is OK to do.
|
||||
// try to lock media and spin up
|
||||
@@ -529,7 +529,7 @@ uint8_t BulkOnly::Init(uint8_t parent __attribute__((unused)), uint8_t port __at
|
||||
* @param proto
|
||||
* @param pep
|
||||
*/
|
||||
void BulkOnly::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto __attribute__((unused)), const USB_ENDPOINT_DESCRIPTOR * pep) {
|
||||
void BulkOnly::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto __attribute__((unused)), const USB_FD_ENDPOINT_DESCRIPTOR * pep) {
|
||||
ErrorMessage<uint8_t> (PSTR("Conf.Val"), conf);
|
||||
ErrorMessage<uint8_t> (PSTR("Iface Num"), iface);
|
||||
ErrorMessage<uint8_t> (PSTR("Alt.Set"), alt);
|
||||
@@ -765,7 +765,7 @@ uint8_t BulkOnly::Page3F(uint8_t lun) {
|
||||
#ifdef SKIP_WRITE_PROTECT
|
||||
return 0;
|
||||
#endif
|
||||
uint8_t rc = ModeSense6(lun, 0, 0x3f, 0, 192, buf);
|
||||
uint8_t rc = ModeSense6(lun, 0, 0x3F, 0, 192, buf);
|
||||
if (!rc) {
|
||||
WriteOk[lun] = ((buf[2] & 0x80) == 0);
|
||||
Notify(PSTR("Mode Sense: "), 0x80);
|
||||
@@ -828,7 +828,6 @@ uint8_t BulkOnly::ClearEpHalt(uint8_t index) {
|
||||
|
||||
/**
|
||||
* For driver use only.
|
||||
*
|
||||
*/
|
||||
void BulkOnly::Reset() {
|
||||
while (pUsb->ctrlReq(bAddress, 0, bmREQ_MASSOUT, MASS_REQ_BOMSR, 0, 0, bIface, 0, 0, nullptr, nullptr) == 0x01) delay(6);
|
||||
@@ -957,12 +956,6 @@ uint8_t BulkOnly::HandleUsbError(uint8_t error, uint8_t index) {
|
||||
return ((error && !count) ? MASS_ERR_GENERAL_USB_ERROR : MASS_ERR_SUCCESS);
|
||||
}
|
||||
|
||||
#if MS_WANT_PARSER
|
||||
uint8_t BulkOnly::Transaction(CommandBlockWrapper *pcbw, uint16_t buf_size, void *buf) {
|
||||
return Transaction(CommandBlockWrapper *pcbw, uint16_t buf_size, void *buf, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* For driver use only.
|
||||
*
|
||||
@@ -973,9 +966,7 @@ uint8_t BulkOnly::HandleUsbError(uint8_t error, uint8_t index) {
|
||||
* @return
|
||||
*/
|
||||
uint8_t BulkOnly::Transaction(CommandBlockWrapper *pcbw, uint16_t buf_size, void *buf
|
||||
#if MS_WANT_PARSER
|
||||
, uint8_t flags
|
||||
#endif
|
||||
OPTARG(MS_WANT_PARSER, uint8_t flags/*=0*/)
|
||||
) {
|
||||
#if MS_WANT_PARSER
|
||||
uint16_t bytes = (pcbw->dCBWDataTransferLength > buf_size) ? buf_size : pcbw->dCBWDataTransferLength;
|
||||
@@ -1163,10 +1154,9 @@ uint8_t BulkOnly::HandleSCSIError(uint8_t status) {
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
*
|
||||
* @param ep_ptr
|
||||
*/
|
||||
void BulkOnly::PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR * ep_ptr) {
|
||||
void BulkOnly::PrintEndpointDescriptor(const USB_FD_ENDPOINT_DESCRIPTOR * ep_ptr) {
|
||||
Notify(PSTR("Endpoint descriptor:"), 0x80);
|
||||
Notify(PSTR("\r\nLength:\t\t"), 0x80);
|
||||
D_PrintHex<uint8_t> (ep_ptr->bLength, 0x80);
|
||||
@@ -1205,10 +1195,10 @@ uint8_t BulkOnly::Read(uint8_t lun __attribute__((unused)), uint32_t addr __attr
|
||||
|
||||
cbw.CBWCB[0] = SCSI_CMD_READ_10;
|
||||
cbw.CBWCB[8] = blocks;
|
||||
cbw.CBWCB[2] = ((addr >> 24) & 0xff);
|
||||
cbw.CBWCB[3] = ((addr >> 16) & 0xff);
|
||||
cbw.CBWCB[4] = ((addr >> 8) & 0xff);
|
||||
cbw.CBWCB[5] = (addr & 0xff);
|
||||
cbw.CBWCB[2] = ((addr >> 24) & 0xFF);
|
||||
cbw.CBWCB[3] = ((addr >> 16) & 0xFF);
|
||||
cbw.CBWCB[4] = ((addr >> 8) & 0xFF);
|
||||
cbw.CBWCB[5] = (addr & 0xFF);
|
||||
|
||||
return HandleSCSIError(Transaction(&cbw, bsize, prs, 1));
|
||||
#else
|
||||
|
15
Marlin/src/sd/usb_flashdrive/lib-uhs2/masstorage.h
Executable file → Normal file
15
Marlin/src/sd/usb_flashdrive/lib-uhs2/masstorage.h
Executable file → Normal file
@@ -19,7 +19,7 @@
|
||||
* -------------------
|
||||
*
|
||||
* Circuits At Home, LTD
|
||||
* Web : http://www.circuitsathome.com
|
||||
* Web : https://www.circuitsathome.com
|
||||
* e-mail : support@circuitsathome.com
|
||||
*/
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
#define MASS_CMD_DIR_IN 0x80 //(1 << 7)
|
||||
|
||||
/*
|
||||
* Reference documents from T10 (http://www.t10.org)
|
||||
* Reference documents from T10 (https://www.t10.org)
|
||||
* SCSI Primary Commands - 3 (SPC-3)
|
||||
* SCSI Block Commands - 2 (SBC-2)
|
||||
* Multi-Media Commands - 5 (MMC-5)
|
||||
@@ -214,7 +214,7 @@ struct CDB6 {
|
||||
public:
|
||||
|
||||
CDB6(uint8_t _Opcode, uint8_t _LUN, uint32_t LBA, uint8_t _AllocationLength, uint8_t _Control) :
|
||||
Opcode(_Opcode), LBAMSB(BGRAB2(LBA) & 0x1f), LUN(_LUN), LBAHB(BGRAB1(LBA)), LBALB(BGRAB0(LBA)),
|
||||
Opcode(_Opcode), LBAMSB(BGRAB2(LBA) & 0x1F), LUN(_LUN), LBAHB(BGRAB1(LBA)), LBALB(BGRAB0(LBA)),
|
||||
AllocationLength(_AllocationLength), Control(_Control) {
|
||||
}
|
||||
|
||||
@@ -491,7 +491,7 @@ protected:
|
||||
uint16_t CurrentSectorSize[MASS_MAX_SUPPORTED_LUN]; // Sector size, clipped to 16 bits
|
||||
bool LUNOk[MASS_MAX_SUPPORTED_LUN]; // use this to check for media changes.
|
||||
bool WriteOk[MASS_MAX_SUPPORTED_LUN];
|
||||
void PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR* ep_ptr);
|
||||
void PrintEndpointDescriptor(const USB_FD_ENDPOINT_DESCRIPTOR* ep_ptr);
|
||||
|
||||
// Additional Initialization Method for Subclasses
|
||||
|
||||
@@ -526,7 +526,7 @@ public:
|
||||
virtual uint8_t GetAddress() { return bAddress; }
|
||||
|
||||
// UsbConfigXtracter implementation
|
||||
void EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *ep);
|
||||
void EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_FD_ENDPOINT_DESCRIPTOR *ep);
|
||||
|
||||
virtual bool DEVCLASSOK(uint8_t klass) { return klass == USB_CLASS_MASS_STORAGE; }
|
||||
|
||||
@@ -553,10 +553,7 @@ private:
|
||||
bool IsValidCSW(CommandStatusWrapper *pcsw, CommandBlockWrapperBase *pcbw);
|
||||
|
||||
uint8_t ClearEpHalt(uint8_t index);
|
||||
#if MS_WANT_PARSER
|
||||
uint8_t Transaction(CommandBlockWrapper *cbw, uint16_t bsize, void *buf, uint8_t flags);
|
||||
#endif
|
||||
uint8_t Transaction(CommandBlockWrapper *cbw, uint16_t bsize, void *buf);
|
||||
uint8_t Transaction(CommandBlockWrapper *cbw, uint16_t bsize, void *buf OPTARG(MS_WANT_PARSER, uint8_t flags=0));
|
||||
uint8_t HandleUsbError(uint8_t error, uint8_t index);
|
||||
uint8_t HandleSCSIError(uint8_t status);
|
||||
};
|
||||
|
30
Marlin/src/sd/usb_flashdrive/lib-uhs2/max3421e.h
Executable file → Normal file
30
Marlin/src/sd/usb_flashdrive/lib-uhs2/max3421e.h
Executable file → Normal file
@@ -19,7 +19,7 @@
|
||||
* -------------------
|
||||
*
|
||||
* Circuits At Home, LTD
|
||||
* Web : http://www.circuitsathome.com
|
||||
* Web : https://www.circuitsathome.com
|
||||
* e-mail : support@circuitsathome.com
|
||||
*/
|
||||
#pragma once
|
||||
@@ -67,7 +67,7 @@
|
||||
|
||||
#define rCPUCTL 0x80 //16<<3
|
||||
/* CPUCTL Bits */
|
||||
#define bmPUSLEWID1 0x80 //b7
|
||||
#define bmPULSEWID1 0x80 //b7
|
||||
#define bmPULSEWID0 0x40 //b6
|
||||
#define bmIE 0x01 //b0
|
||||
|
||||
@@ -86,7 +86,7 @@
|
||||
|
||||
#define rREVISION 0x90 //18<<3
|
||||
|
||||
#define rIOPINS1 0xa0 //20<<3
|
||||
#define rIOPINS1 0xA0 //20<<3
|
||||
|
||||
/* IOPINS1 Bits */
|
||||
#define bmGPOUT0 0x01
|
||||
@@ -98,7 +98,7 @@
|
||||
#define bmGPIN2 0x40
|
||||
#define bmGPIN3 0x80
|
||||
|
||||
#define rIOPINS2 0xa8 //21<<3
|
||||
#define rIOPINS2 0xA8 //21<<3
|
||||
/* IOPINS2 Bits */
|
||||
#define bmGPOUT4 0x01
|
||||
#define bmGPOUT5 0x02
|
||||
@@ -109,7 +109,7 @@
|
||||
#define bmGPIN6 0x40
|
||||
#define bmGPIN7 0x80
|
||||
|
||||
#define rGPINIRQ 0xb0 //22<<3
|
||||
#define rGPINIRQ 0xB0 //22<<3
|
||||
/* GPINIRQ Bits */
|
||||
#define bmGPINIRQ0 0x01
|
||||
#define bmGPINIRQ1 0x02
|
||||
@@ -120,7 +120,7 @@
|
||||
#define bmGPINIRQ6 0x40
|
||||
#define bmGPINIRQ7 0x80
|
||||
|
||||
#define rGPINIEN 0xb8 //23<<3
|
||||
#define rGPINIEN 0xB8 //23<<3
|
||||
/* GPINIEN Bits */
|
||||
#define bmGPINIEN0 0x01
|
||||
#define bmGPINIEN1 0x02
|
||||
@@ -131,7 +131,7 @@
|
||||
#define bmGPINIEN6 0x40
|
||||
#define bmGPINIEN7 0x80
|
||||
|
||||
#define rGPINPOL 0xc0 //24<<3
|
||||
#define rGPINPOL 0xC0 //24<<3
|
||||
/* GPINPOL Bits */
|
||||
#define bmGPINPOL0 0x01
|
||||
#define bmGPINPOL1 0x02
|
||||
@@ -142,7 +142,7 @@
|
||||
#define bmGPINPOL6 0x40
|
||||
#define bmGPINPOL7 0x80
|
||||
|
||||
#define rHIRQ 0xc8 //25<<3
|
||||
#define rHIRQ 0xC8 //25<<3
|
||||
/* HIRQ Bits */
|
||||
#define bmBUSEVENTIRQ 0x01 // indicates BUS Reset Done or BUS Resume
|
||||
#define bmRWUIRQ 0x02
|
||||
@@ -153,7 +153,7 @@
|
||||
#define bmFRAMEIRQ 0x40
|
||||
#define bmHXFRDNIRQ 0x80
|
||||
|
||||
#define rHIEN 0xd0 //26<<3
|
||||
#define rHIEN 0xD0 //26<<3
|
||||
|
||||
/* HIEN Bits */
|
||||
#define bmBUSEVENTIE 0x01
|
||||
@@ -165,7 +165,7 @@
|
||||
#define bmFRAMEIE 0x40
|
||||
#define bmHXFRDNIE 0x80
|
||||
|
||||
#define rMODE 0xd8 //27<<3
|
||||
#define rMODE 0xD8 //27<<3
|
||||
|
||||
/* MODE Bits */
|
||||
#define bmHOST 0x01
|
||||
@@ -177,9 +177,9 @@
|
||||
#define bmDMPULLDN 0x40
|
||||
#define bmDPPULLDN 0x80
|
||||
|
||||
#define rPERADDR 0xe0 //28<<3
|
||||
#define rPERADDR 0xE0 //28<<3
|
||||
|
||||
#define rHCTL 0xe8 //29<<3
|
||||
#define rHCTL 0xE8 //29<<3
|
||||
/* HCTL Bits */
|
||||
#define bmBUSRST 0x01
|
||||
#define bmFRMRST 0x02
|
||||
@@ -190,7 +190,7 @@
|
||||
#define bmSNDTOG0 0x40
|
||||
#define bmSNDTOG1 0x80
|
||||
|
||||
#define rHXFR 0xf0 //30<<3
|
||||
#define rHXFR 0xF0 //30<<3
|
||||
|
||||
#undef tokSETUP
|
||||
#undef tokIN
|
||||
@@ -210,7 +210,7 @@
|
||||
#define tokISOIN 0x40 // HS=0, ISO=1, OUTNIN=0, SETUP=0
|
||||
#define tokISOOUT 0x60 // HS=0, ISO=1, OUTNIN=1, SETUP=0
|
||||
|
||||
#define rHRSL 0xf8 //31<<3
|
||||
#define rHRSL 0xF8 //31<<3
|
||||
|
||||
/* HRSL Bits */
|
||||
#define bmRCVTOGRD 0x10
|
||||
@@ -218,7 +218,7 @@
|
||||
#define bmKSTATUS 0x40
|
||||
#define bmJSTATUS 0x80
|
||||
#define bmSE0 0x00 //SE0 - disconnect state
|
||||
#define bmSE1 0xc0 //SE1 - illegal state
|
||||
#define bmSE1 0xC0 //SE1 - illegal state
|
||||
|
||||
/* Host error result codes, the 4 LSB's in the HRSL register */
|
||||
#define hrSUCCESS 0x00
|
||||
|
4
Marlin/src/sd/usb_flashdrive/lib-uhs2/message.cpp
Executable file → Normal file
4
Marlin/src/sd/usb_flashdrive/lib-uhs2/message.cpp
Executable file → Normal file
@@ -19,7 +19,7 @@
|
||||
* -------------------
|
||||
*
|
||||
* Circuits At Home, LTD
|
||||
* Web : http://www.circuitsathome.com
|
||||
* Web : https://www.circuitsathome.com
|
||||
* e-mail : support@circuitsathome.com
|
||||
*/
|
||||
|
||||
@@ -37,7 +37,7 @@ int UsbDEBUGlvl = 0x80;
|
||||
void E_Notifyc(char c, int lvl) {
|
||||
if (UsbDEBUGlvl < lvl) return;
|
||||
USB_HOST_SERIAL.print(c
|
||||
#if !defined(ARDUINO) || ARDUINO < 100
|
||||
#if !defined(ARDUINO) && !defined(ARDUINO_ARCH_LPC176X)
|
||||
, BYTE
|
||||
#endif
|
||||
);
|
||||
|
2
Marlin/src/sd/usb_flashdrive/lib-uhs2/message.h
Executable file → Normal file
2
Marlin/src/sd/usb_flashdrive/lib-uhs2/message.h
Executable file → Normal file
@@ -19,7 +19,7 @@
|
||||
* -------------------
|
||||
*
|
||||
* Circuits At Home, LTD
|
||||
* Web : http://www.circuitsathome.com
|
||||
* Web : https://www.circuitsathome.com
|
||||
* e-mail : support@circuitsathome.com
|
||||
*/
|
||||
#pragma once
|
||||
|
2
Marlin/src/sd/usb_flashdrive/lib-uhs2/parsetools.cpp
Executable file → Normal file
2
Marlin/src/sd/usb_flashdrive/lib-uhs2/parsetools.cpp
Executable file → Normal file
@@ -19,7 +19,7 @@
|
||||
* -------------------
|
||||
*
|
||||
* Circuits At Home, LTD
|
||||
* Web : http://www.circuitsathome.com
|
||||
* Web : https://www.circuitsathome.com
|
||||
* e-mail : support@circuitsathome.com
|
||||
*/
|
||||
|
||||
|
2
Marlin/src/sd/usb_flashdrive/lib-uhs2/parsetools.h
Executable file → Normal file
2
Marlin/src/sd/usb_flashdrive/lib-uhs2/parsetools.h
Executable file → Normal file
@@ -19,7 +19,7 @@
|
||||
* -------------------
|
||||
*
|
||||
* Circuits At Home, LTD
|
||||
* Web : http://www.circuitsathome.com
|
||||
* Web : https://www.circuitsathome.com
|
||||
* e-mail : support@circuitsathome.com
|
||||
*/
|
||||
#pragma once
|
||||
|
14
Marlin/src/sd/usb_flashdrive/lib-uhs2/printhex.h
Executable file → Normal file
14
Marlin/src/sd/usb_flashdrive/lib-uhs2/printhex.h
Executable file → Normal file
@@ -19,7 +19,7 @@
|
||||
* -------------------
|
||||
*
|
||||
* Circuits At Home, LTD
|
||||
* Web : http://www.circuitsathome.com
|
||||
* Web : https://www.circuitsathome.com
|
||||
* e-mail : support@circuitsathome.com
|
||||
*/
|
||||
#pragma once
|
||||
@@ -32,12 +32,12 @@ void E_Notifyc(char c, int lvl);
|
||||
|
||||
template <class T>
|
||||
void PrintHex(T val, int lvl) {
|
||||
int num_nibbles = sizeof (T) * 2;
|
||||
int num_nybbles = sizeof (T) * 2;
|
||||
do {
|
||||
char v = 48 + (((val >> (num_nibbles - 1) * 4)) & 0x0f);
|
||||
char v = 48 + (((val >> (num_nybbles - 1) * 4)) & 0x0F);
|
||||
if (v > 57) v += 7;
|
||||
E_Notifyc(v, lvl);
|
||||
} while (--num_nibbles);
|
||||
} while (--num_nybbles);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
@@ -48,12 +48,12 @@ void PrintBin(T val, int lvl) {
|
||||
|
||||
template <class T>
|
||||
void SerialPrintHex(T val) {
|
||||
int num_nibbles = sizeof (T) * 2;
|
||||
int num_nybbles = sizeof (T) * 2;
|
||||
do {
|
||||
char v = 48 + (((val >> (num_nibbles - 1) * 4)) & 0x0f);
|
||||
char v = 48 + (((val >> (num_nybbles - 1) * 4)) & 0x0F);
|
||||
if (v > 57) v += 7;
|
||||
USB_HOST_SERIAL.print(v);
|
||||
} while (--num_nibbles);
|
||||
} while (--num_nybbles);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
|
6
Marlin/src/sd/usb_flashdrive/lib-uhs2/settings.h
Executable file → Normal file
6
Marlin/src/sd/usb_flashdrive/lib-uhs2/settings.h
Executable file → Normal file
@@ -19,7 +19,7 @@
|
||||
* -------------------
|
||||
*
|
||||
* Circuits At Home, LTD
|
||||
* Web : http://www.circuitsathome.com
|
||||
* Web : https://www.circuitsathome.com
|
||||
* e-mail : support@circuitsathome.com
|
||||
*/
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
* For example Serial3.
|
||||
*/
|
||||
#if ENABLED(USB_FLASH_DRIVE_SUPPORT)
|
||||
#define USB_HOST_SERIAL MYSERIAL0
|
||||
#define USB_HOST_SERIAL MYSERIAL1
|
||||
#endif
|
||||
|
||||
#ifndef USB_HOST_SERIAL
|
||||
@@ -132,7 +132,7 @@
|
||||
#if GCC_VERSION < 40602 // Test for GCC < 4.6.2
|
||||
#ifdef PROGMEM
|
||||
#undef PROGMEM
|
||||
#define PROGMEM __attribute__((section(".progmem.data"))) // Workaround for http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34734#c4
|
||||
#define PROGMEM __attribute__((section(".progmem.data"))) // Workaround for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=34734#c4
|
||||
#ifdef PSTR
|
||||
#undef PSTR
|
||||
#define PSTR(s) (__extension__({static const char __c[] PROGMEM = (s); &__c[0];})) // Copied from pgmspace.h in avr-libc source
|
||||
|
10
Marlin/src/sd/usb_flashdrive/lib-uhs2/usb_ch9.h
Executable file → Normal file
10
Marlin/src/sd/usb_flashdrive/lib-uhs2/usb_ch9.h
Executable file → Normal file
@@ -19,7 +19,7 @@
|
||||
* -------------------
|
||||
*
|
||||
* Circuits At Home, LTD
|
||||
* Web : http://www.circuitsathome.com
|
||||
* Web : https://www.circuitsathome.com
|
||||
* e-mail : support@circuitsathome.com
|
||||
*/
|
||||
|
||||
@@ -116,7 +116,7 @@ typedef struct {
|
||||
uint8_t iProduct; // Index of String Descriptor describing the product.
|
||||
uint8_t iSerialNumber; // Index of String Descriptor with the device's serial number.
|
||||
uint8_t bNumConfigurations; // Number of possible configurations.
|
||||
} __attribute__((packed)) USB_DEVICE_DESCRIPTOR;
|
||||
} __attribute__((packed)) USB_FD_DEVICE_DESCRIPTOR;
|
||||
|
||||
/* Configuration descriptor structure */
|
||||
typedef struct {
|
||||
@@ -128,7 +128,7 @@ typedef struct {
|
||||
uint8_t iConfiguration; // Index of String Descriptor describing the configuration.
|
||||
uint8_t bmAttributes; // Configuration characteristics.
|
||||
uint8_t bMaxPower; // Maximum power consumed by this configuration.
|
||||
} __attribute__((packed)) USB_CONFIGURATION_DESCRIPTOR;
|
||||
} __attribute__((packed)) USB_FD_CONFIGURATION_DESCRIPTOR;
|
||||
|
||||
/* Interface descriptor structure */
|
||||
typedef struct {
|
||||
@@ -141,7 +141,7 @@ typedef struct {
|
||||
uint8_t bInterfaceSubClass; // Subclass code (assigned by the USB-IF).
|
||||
uint8_t bInterfaceProtocol; // Protocol code (assigned by the USB-IF). 0xFF-Vendor specific.
|
||||
uint8_t iInterface; // Index of String Descriptor describing the interface.
|
||||
} __attribute__((packed)) USB_INTERFACE_DESCRIPTOR;
|
||||
} __attribute__((packed)) USB_FD_INTERFACE_DESCRIPTOR;
|
||||
|
||||
/* Endpoint descriptor structure */
|
||||
typedef struct {
|
||||
@@ -151,7 +151,7 @@ typedef struct {
|
||||
uint8_t bmAttributes; // Endpoint transfer type.
|
||||
uint16_t wMaxPacketSize; // Maximum packet size.
|
||||
uint8_t bInterval; // Polling interval in frames.
|
||||
} __attribute__((packed)) USB_ENDPOINT_DESCRIPTOR;
|
||||
} __attribute__((packed)) USB_FD_ENDPOINT_DESCRIPTOR;
|
||||
|
||||
/* HID descriptor */
|
||||
typedef struct {
|
||||
|
18
Marlin/src/sd/usb_flashdrive/lib-uhs2/usbhost.cpp
Executable file → Normal file
18
Marlin/src/sd/usb_flashdrive/lib-uhs2/usbhost.cpp
Executable file → Normal file
@@ -16,7 +16,7 @@
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* To view a copy of the GNU General Public License, go to the following *
|
||||
* location: <http://www.gnu.org/licenses/>. *
|
||||
* location: <https://www.gnu.org/licenses/>. *
|
||||
****************************************************************************/
|
||||
|
||||
/* What follows is a modified version of the MAX3421e originally defined in
|
||||
@@ -51,7 +51,7 @@ void MAX3421e::regWr(uint8_t reg, uint8_t data) {
|
||||
|
||||
// multiple-byte write
|
||||
// return a pointer to memory position after last written
|
||||
uint8_t* MAX3421e::bytesWr(uint8_t reg, uint8_t nbytes, uint8_t* data_p) {
|
||||
uint8_t* MAX3421e::bytesWr(uint8_t reg, uint8_t nbytes, uint8_t *data_p) {
|
||||
cs();
|
||||
spiSend(reg | 0x02);
|
||||
while (nbytes--) spiSend(*data_p++);
|
||||
@@ -79,7 +79,7 @@ uint8_t MAX3421e::regRd(uint8_t reg) {
|
||||
// multiple-byte register read
|
||||
|
||||
// return a pointer to a memory position after last read
|
||||
uint8_t* MAX3421e::bytesRd(uint8_t reg, uint8_t nbytes, uint8_t* data_p) {
|
||||
uint8_t* MAX3421e::bytesRd(uint8_t reg, uint8_t nbytes, uint8_t *data_p) {
|
||||
cs();
|
||||
spiSend(reg);
|
||||
while (nbytes--) *data_p++ = spiRec();
|
||||
@@ -90,7 +90,7 @@ uint8_t* MAX3421e::bytesRd(uint8_t reg, uint8_t nbytes, uint8_t* data_p) {
|
||||
|
||||
// GPIN pins are in high nybbles of IOPINS1, IOPINS2
|
||||
uint8_t MAX3421e::gpioRd() {
|
||||
return (regRd(rIOPINS2) & 0xf0) | // pins 4-7, clean lower nybble
|
||||
return (regRd(rIOPINS2) & 0xF0) | // pins 4-7, clean lower nybble
|
||||
(regRd(rIOPINS1) >> 4); // shift low bits and OR with upper from previous operation.
|
||||
}
|
||||
|
||||
@@ -114,20 +114,14 @@ bool MAX3421e::start() {
|
||||
ncs();
|
||||
spiBegin();
|
||||
|
||||
spiInit(
|
||||
#ifdef SPI_SPEED
|
||||
SPI_SPEED
|
||||
#else
|
||||
SPI_FULL_SPEED
|
||||
#endif
|
||||
);
|
||||
spiInit(SD_SPI_SPEED);
|
||||
|
||||
// MAX3421e - full-duplex, level interrupt, vbus off.
|
||||
regWr(rPINCTL, (bmFDUPSPI | bmINTLEVEL | GPX_VBDET));
|
||||
|
||||
const uint8_t revision = regRd(rREVISION);
|
||||
if (revision == 0x00 || revision == 0xFF) {
|
||||
SERIAL_ECHOLNPAIR("Revision register appears incorrect on MAX3421e initialization. Got ", revision);
|
||||
SERIAL_ECHOLNPGM("Revision register appears incorrect on MAX3421e initialization. Got ", revision);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
6
Marlin/src/sd/usb_flashdrive/lib-uhs2/usbhost.h
Executable file → Normal file
6
Marlin/src/sd/usb_flashdrive/lib-uhs2/usbhost.h
Executable file → Normal file
@@ -16,7 +16,7 @@
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* To view a copy of the GNU General Public License, go to the following *
|
||||
* location: <http://www.gnu.org/licenses/>. *
|
||||
* location: <https://www.gnu.org/licenses/>. *
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
@@ -37,10 +37,10 @@ class MAX3421e {
|
||||
bool start();
|
||||
|
||||
void regWr(uint8_t reg, uint8_t data);
|
||||
uint8_t* bytesWr(uint8_t reg, uint8_t nbytes, uint8_t* data_p);
|
||||
uint8_t* bytesWr(uint8_t reg, uint8_t nbytes, uint8_t *data_p);
|
||||
void gpioWr(uint8_t data);
|
||||
uint8_t regRd(uint8_t reg);
|
||||
uint8_t* bytesRd(uint8_t reg, uint8_t nbytes, uint8_t* data_p);
|
||||
uint8_t* bytesRd(uint8_t reg, uint8_t nbytes, uint8_t *data_p);
|
||||
uint8_t gpioRd();
|
||||
bool reset();
|
||||
|
||||
|
4
Marlin/src/sd/usb_flashdrive/lib-uhs3/README.txt
Executable file → Normal file
4
Marlin/src/sd/usb_flashdrive/lib-uhs3/README.txt
Executable file → Normal file
@@ -16,7 +16,7 @@ usb_flashdrive/lib github.com/felis/UHS30 GPLv2 or later
|
||||
==== MARLIN INTEGRATION WORK ====
|
||||
|
||||
All additional work done to integrate USB into Marlin was performed by
|
||||
AlephObjects, Inc. and is licensed under the GPLv3.
|
||||
LulzBot and is licensed under the GPLv3.
|
||||
|
||||
This version of UHS3 has been modified for better compatibility with Marlin.
|
||||
The upstream version of UHS 3.0 runs a frame timer interrupt every 1 ms to
|
||||
@@ -27,5 +27,3 @@ IRQ.
|
||||
|
||||
SKIP_PAGE3F and USB_NO_TEST_UNIT_READY were added to work around bugs with
|
||||
certain devices.
|
||||
|
||||
-- marcio@alephobjects.com
|
||||
|
4
Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_BULK_STORAGE/UHS_BULK_STORAGE.h
Executable file → Normal file
4
Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_BULK_STORAGE/UHS_BULK_STORAGE.h
Executable file → Normal file
@@ -20,7 +20,7 @@ Contact information
|
||||
-------------------
|
||||
|
||||
Circuits At Home, LTD
|
||||
Web : http://www.circuitsathome.com
|
||||
Web : https://www.circuitsathome.com
|
||||
e-mail : support@circuitsathome.com
|
||||
*/
|
||||
|
||||
@@ -174,7 +174,7 @@ protected:
|
||||
volatile uint16_t CurrentSectorSize[MASS_MAX_SUPPORTED_LUN]; // Sector size, clipped to 16 bits
|
||||
volatile bool LUNOk[MASS_MAX_SUPPORTED_LUN]; // use this to check for media changes.
|
||||
volatile bool WriteOk[MASS_MAX_SUPPORTED_LUN];
|
||||
void PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR* ep_ptr);
|
||||
void PrintEndpointDescriptor(const USB_FD_ENDPOINT_DESCRIPTOR* ep_ptr);
|
||||
|
||||
public:
|
||||
UHS_Bulk_Storage(UHS_USB_HOST_BASE *p);
|
||||
|
19
Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_BULK_STORAGE/UHS_BULK_STORAGE_INLINE.h
Executable file → Normal file
19
Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_BULK_STORAGE/UHS_BULK_STORAGE_INLINE.h
Executable file → Normal file
@@ -20,7 +20,7 @@ Contact information
|
||||
-------------------
|
||||
|
||||
Circuits At Home, LTD
|
||||
Web : http://www.circuitsathome.com
|
||||
Web : https://www.circuitsathome.com
|
||||
e-mail : support@circuitsathome.com
|
||||
*/
|
||||
|
||||
@@ -318,7 +318,6 @@ UHS_NI UHS_Bulk_Storage::UHS_Bulk_Storage(UHS_USB_HOST_BASE *p) {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param ei Enumeration information
|
||||
* @return true if this interface driver can handle this interface description
|
||||
*/
|
||||
@@ -375,7 +374,6 @@ uint8_t UHS_NI UHS_Bulk_Storage::SetInterface(ENUMERATION_INFO *ei) {
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
* @return 0 for success
|
||||
*/
|
||||
uint8_t UHS_NI UHS_Bulk_Storage::Start() {
|
||||
@@ -455,9 +453,9 @@ uint8_t UHS_NI UHS_Bulk_Storage::Start() {
|
||||
for(uint8_t lun = 0; lun <= bMaxLUN; lun++) {
|
||||
if(!UHS_SLEEP_MS(3)) goto FailUnPlug;
|
||||
#ifndef USB_NO_TEST_UNIT_READY
|
||||
uint8_t tries = 0xf0;
|
||||
uint8_t tries = 0xF0;
|
||||
while((rcode = TestUnitReady(lun))) {
|
||||
BS_HOST_DEBUG("\r\nTry %2.2x TestUnitReady %2.2x\r\n", tries - 0xf0, rcode);
|
||||
BS_HOST_DEBUG("\r\nTry %2.2x TestUnitReady %2.2x\r\n", tries - 0xF0, rcode);
|
||||
if(rcode == 0x08) break; // break on no media, this is OK to do.
|
||||
if(rcode == UHS_BULK_ERR_DEVICE_DISCONNECTED) goto FailUnPlug;
|
||||
if(rcode == UHS_BULK_ERR_INVALID_CSW) goto Fail;
|
||||
@@ -477,7 +475,7 @@ uint8_t UHS_NI UHS_Bulk_Storage::Start() {
|
||||
if(!UHS_SLEEP_MS(3)) goto FailUnPlug;
|
||||
if(MediaCTL(lun, 1) == UHS_BULK_ERR_DEVICE_DISCONNECTED) goto FailUnPlug; // I actually have a USB stick that needs this!
|
||||
}
|
||||
BS_HOST_DEBUG("\r\nTry %2.2x TestUnitReady %2.2x\r\n", tries - 0xf0, rcode);
|
||||
BS_HOST_DEBUG("\r\nTry %2.2x TestUnitReady %2.2x\r\n", tries - 0xF0, rcode);
|
||||
if(!rcode) {
|
||||
if(!UHS_SLEEP_MS(3)) goto FailUnPlug;
|
||||
BS_HOST_DEBUG("CheckLUN...\r\n");
|
||||
@@ -581,7 +579,7 @@ bool UHS_NI UHS_Bulk_Storage::CheckLUN(uint8_t lun) {
|
||||
|
||||
CurrentCapacity[lun] = UHS_BYTES_TO_UINT32(capacity.data[0], capacity.data[1], capacity.data[2], capacity.data[3]) + 1;
|
||||
if(CurrentCapacity[lun] == /*0xffffffffLU */ 0x01LU || CurrentCapacity[lun] == 0x00LU) {
|
||||
// Buggy firmware will report 0xffffffff or 0 for no media
|
||||
// Buggy firmware will report 0xFFFFFFFF or 0 for no media
|
||||
#ifdef DEBUG_USB_HOST
|
||||
if(CurrentCapacity[lun])
|
||||
ErrorMessage<uint8_t > (PSTR(">>>>>>>>>>>>>>>>BUGGY FIRMWARE. CAPACITY FAIL ON LUN"), lun);
|
||||
@@ -628,7 +626,6 @@ void UHS_NI UHS_Bulk_Storage::CheckMedia() {
|
||||
|
||||
/**
|
||||
* For driver use only.
|
||||
*
|
||||
*/
|
||||
void UHS_NI UHS_Bulk_Storage::Poll() {
|
||||
if((long)(millis() - qNextPollTime) >= 0L) {
|
||||
@@ -759,7 +756,7 @@ uint8_t UHS_NI UHS_Bulk_Storage::Page3F(uint8_t lun) {
|
||||
buf[i] = 0x00;
|
||||
}
|
||||
WriteOk[lun] = true;
|
||||
uint8_t rc = ModeSense6(lun, 0, 0x3f, 0, 192, buf);
|
||||
uint8_t rc = ModeSense6(lun, 0, 0x3F, 0, 192, buf);
|
||||
if(!rc) {
|
||||
WriteOk[lun] = ((buf[2] & 0x80) == 0);
|
||||
#ifdef DEBUG_USB_HOST
|
||||
@@ -839,7 +836,6 @@ uint8_t UHS_NI UHS_Bulk_Storage::ClearEpHalt(uint8_t index) {
|
||||
|
||||
/**
|
||||
* For driver use only.
|
||||
*
|
||||
*/
|
||||
void UHS_NI UHS_Bulk_Storage::Reset() {
|
||||
if(!bAddress) return;
|
||||
@@ -1185,10 +1181,9 @@ uint8_t UHS_NI UHS_Bulk_Storage::HandleSCSIError(uint8_t status) {
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
*
|
||||
* @param ep_ptr
|
||||
*/
|
||||
void UHS_NI UHS_Bulk_Storage::PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR * ep_ptr) {
|
||||
void UHS_NI UHS_Bulk_Storage::PrintEndpointDescriptor(const USB_FD_ENDPOINT_DESCRIPTOR * ep_ptr) {
|
||||
Notify(PSTR("Endpoint descriptor:"), 0x80);
|
||||
Notify(PSTR("\r\nLength:\t\t"), 0x80);
|
||||
D_PrintHex<uint8_t > (ep_ptr->bLength, 0x80);
|
||||
|
6
Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_BULK_STORAGE/UHS_SCSI.h
Executable file → Normal file
6
Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_BULK_STORAGE/UHS_SCSI.h
Executable file → Normal file
@@ -20,7 +20,7 @@ Contact information
|
||||
-------------------
|
||||
|
||||
Circuits At Home, LTD
|
||||
Web : http://www.circuitsathome.com
|
||||
Web : https://www.circuitsathome.com
|
||||
e-mail : support@circuitsathome.com
|
||||
*/
|
||||
|
||||
@@ -28,7 +28,7 @@ e-mail : support@circuitsathome.com
|
||||
#define UHS_SCSI_H
|
||||
|
||||
/*
|
||||
* Reference documents from T10 (http://www.t10.org)
|
||||
* Reference documents from T10 (https://www.t10.org)
|
||||
* SCSI Primary Commands - 3 (SPC-3)
|
||||
* SCSI Block Commands - 2 (SBC-2)
|
||||
* Multi-Media Commands - 5 (MMC-5)
|
||||
@@ -146,7 +146,7 @@ struct SCSI_CDB6 {
|
||||
public:
|
||||
|
||||
SCSI_CDB6(uint8_t _Opcode, uint8_t _LUN, uint32_t LBA, uint8_t _AllocationLength, uint8_t _Control) :
|
||||
Opcode(_Opcode), LBAMSB(UHS_UINT8_BYTE2(LBA) & 0x1f), LUN(_LUN), LBAHB(UHS_UINT8_BYTE1(LBA)), LBALB(UHS_UINT8_BYTE0(LBA)),
|
||||
Opcode(_Opcode), LBAMSB(UHS_UINT8_BYTE2(LBA) & 0x1F), LUN(_LUN), LBAHB(UHS_UINT8_BYTE1(LBA)), LBALB(UHS_UINT8_BYTE0(LBA)),
|
||||
AllocationLength(_AllocationLength), Control(_Control) {
|
||||
}
|
||||
|
||||
|
2
Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_UNOFFICIAL_IDs.h
Executable file → Normal file
2
Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_UNOFFICIAL_IDs.h
Executable file → Normal file
@@ -20,7 +20,7 @@ Contact information
|
||||
-------------------
|
||||
|
||||
Circuits At Home, LTD
|
||||
Web : http://www.circuitsathome.com
|
||||
Web : https://www.circuitsathome.com
|
||||
e-mail : support@circuitsathome.com
|
||||
*/
|
||||
#ifndef _UHS_UNOFFICIAL_IDs_h
|
||||
|
0
Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_USB_IDs.h
Executable file → Normal file
0
Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_USB_IDs.h
Executable file → Normal file
8
Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_UsbCore.h
Executable file → Normal file
8
Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_UsbCore.h
Executable file → Normal file
@@ -20,7 +20,7 @@ Contact information
|
||||
-------------------
|
||||
|
||||
Circuits At Home, LTD
|
||||
Web : http://www.circuitsathome.com
|
||||
Web : https://www.circuitsathome.com
|
||||
e-mail : support@circuitsathome.com
|
||||
*/
|
||||
|
||||
@@ -189,8 +189,8 @@ e-mail : support@circuitsathome.com
|
||||
#define UHS_USB_HOST_STATE_INITIALIZE 0x10U // Looks like "I"nit
|
||||
|
||||
// Host SE result codes.
|
||||
// Common SE results are stored in the low nybble, all interface drivers understand these plus 0x1f.
|
||||
// Extended SE results are 0x10-0x1e. SE code only understands these internal to the hardware.
|
||||
// Common SE results are stored in the low nybble, all interface drivers understand these plus 0x1F.
|
||||
// Extended SE results are 0x10-0x1E. SE code only understands these internal to the hardware.
|
||||
// Values > 0x1F are driver or other internal error conditions.
|
||||
// Return these result codes from your host controller driver to match the error condition
|
||||
// ALL Non-zero values are errors.
|
||||
@@ -248,7 +248,7 @@ e-mail : support@circuitsathome.com
|
||||
#define UHS_HOST_TRANSFER_MAX_MS 10000 // USB transfer timeout in ms, per section 9.2.6.1 of USB 2.0 spec
|
||||
#define UHS_HOST_TRANSFER_RETRY_MAXIMUM 3 // 3 retry limit for a transfer
|
||||
#define UHS_HOST_DEBOUNCE_DELAY_MS 500 // settle delay in milliseconds
|
||||
#define UHS_HUB_RESET_DELAY_MS 20 // hub port reset delay, 10ms recomended, but can be up to 20ms
|
||||
#define UHS_HUB_RESET_DELAY_MS 20 // hub port reset delay, 10ms recommended, but can be up to 20ms
|
||||
|
||||
//
|
||||
// We only provide the minimum needed information for enumeration.
|
||||
|
2
Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_address.h
Executable file → Normal file
2
Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_address.h
Executable file → Normal file
@@ -20,7 +20,7 @@ Contact information
|
||||
-------------------
|
||||
|
||||
Circuits At Home, LTD
|
||||
Web : http://www.circuitsathome.com
|
||||
Web : https://www.circuitsathome.com
|
||||
e-mail : support@circuitsathome.com
|
||||
*/
|
||||
|
||||
|
2
Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_hexdump.h
Executable file → Normal file
2
Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_hexdump.h
Executable file → Normal file
@@ -20,7 +20,7 @@ Contact information
|
||||
-------------------
|
||||
|
||||
Circuits At Home, LTD
|
||||
Web : http://www.circuitsathome.com
|
||||
Web : https://www.circuitsathome.com
|
||||
e-mail : support@circuitsathome.com
|
||||
*/
|
||||
#if !defined(_usb_h_) || defined(__HEXDUMP_H__)
|
||||
|
2
Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_host.h
Executable file → Normal file
2
Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_host.h
Executable file → Normal file
@@ -20,7 +20,7 @@ Contact information
|
||||
-------------------
|
||||
|
||||
Circuits At Home, LTD
|
||||
Web : http://www.circuitsathome.com
|
||||
Web : https://www.circuitsathome.com
|
||||
e-mail : support@circuitsathome.com
|
||||
*/
|
||||
/* USB functions */
|
||||
|
54
Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_host_INLINE.h
Executable file → Normal file
54
Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_host_INLINE.h
Executable file → Normal file
@@ -20,7 +20,7 @@ Contact information
|
||||
-------------------
|
||||
|
||||
Circuits At Home, LTD
|
||||
Web : http://www.circuitsathome.com
|
||||
Web : https://www.circuitsathome.com
|
||||
e-mail : support@circuitsathome.com
|
||||
*/
|
||||
|
||||
@@ -90,7 +90,7 @@ uint8_t UHS_USB_HOST_BASE::setEpInfoEntry(uint8_t addr, uint8_t iface, uint8_t e
|
||||
}
|
||||
|
||||
/**
|
||||
* sets all enpoint addresses to zero.
|
||||
* sets all endpoint addresses to zero.
|
||||
* Sets all max packet sizes to defaults
|
||||
* Clears all endpoint attributes
|
||||
* Sets bmNakPower to USB_NAK_DEFAULT
|
||||
@@ -101,7 +101,6 @@ uint8_t UHS_USB_HOST_BASE::setEpInfoEntry(uint8_t addr, uint8_t iface, uint8_t e
|
||||
*
|
||||
* @param maxep How many endpoints to initialize
|
||||
* @param device pointer to the device driver instance (this)
|
||||
*
|
||||
*/
|
||||
|
||||
void UHS_USB_HOST_BASE::DeviceDefaults(uint8_t maxep, UHS_USBInterface *interface) {
|
||||
@@ -206,8 +205,7 @@ uint8_t UHS_USB_HOST_BASE::doSoftReset(uint8_t parent, uint8_t port, uint8_t add
|
||||
* will not enumerate without it. For devices that do not
|
||||
* need it, the additional reset is harmless. Here is an
|
||||
* example of one of these documents, see page Five:
|
||||
* http://www.ftdichip.com/Support/Documents/TechnicalNotes/TN_113_Simplified%20Description%20of%20USB%20Device%20Enumeration.pdf
|
||||
*
|
||||
* https://www.ftdichip.com/Support/Documents/TechnicalNotes/TN_113_Simplified%20Description%20of%20USB%20Device%20Enumeration.pdf
|
||||
*
|
||||
*/
|
||||
|
||||
@@ -239,12 +237,12 @@ uint8_t UHS_USB_HOST_BASE::Configuring(uint8_t parent, uint8_t port, uint8_t spe
|
||||
// wrap in {} to throw away the 64 byte buffer when we are done with it
|
||||
{
|
||||
uint8_t buf[biggest];
|
||||
USB_DEVICE_DESCRIPTOR *udd = reinterpret_cast<USB_DEVICE_DESCRIPTOR *>(buf);
|
||||
USB_FD_DEVICE_DESCRIPTOR *udd = reinterpret_cast<USB_FD_DEVICE_DESCRIPTOR *>(buf);
|
||||
#else
|
||||
const uint8_t biggest = 18;
|
||||
uint8_t buf[biggest];
|
||||
USB_DEVICE_DESCRIPTOR *udd = reinterpret_cast<USB_DEVICE_DESCRIPTOR *>(buf);
|
||||
USB_CONFIGURATION_DESCRIPTOR *ucd = reinterpret_cast<USB_CONFIGURATION_DESCRIPTOR *>(buf);
|
||||
USB_FD_DEVICE_DESCRIPTOR *udd = reinterpret_cast<USB_FD_DEVICE_DESCRIPTOR *>(buf);
|
||||
USB_FD_CONFIGURATION_DESCRIPTOR *ucd = reinterpret_cast<USB_FD_CONFIGURATION_DESCRIPTOR *>(buf);
|
||||
#endif
|
||||
|
||||
//for(devConfigIndex = 0; devConfigIndex < UHS_HOST_MAX_INTERFACE_DRIVERS; devConfigIndex++) {
|
||||
@@ -309,7 +307,7 @@ again:
|
||||
sof_delay(200);
|
||||
goto again;
|
||||
}
|
||||
HOST_DEBUG("Configuring error: 0x%2.2x Can't get USB_DEVICE_DESCRIPTOR\r\n", rcode);
|
||||
HOST_DEBUG("Configuring error: 0x%2.2x Can't get USB_FD_DEVICE_DESCRIPTOR\r\n", rcode);
|
||||
return rcode;
|
||||
}
|
||||
|
||||
@@ -378,7 +376,7 @@ again:
|
||||
} // unwrapped, old large buf now invalid and discarded.
|
||||
|
||||
uint8_t buf[18];
|
||||
USB_CONFIGURATION_DESCRIPTOR *ucd = reinterpret_cast<USB_CONFIGURATION_DESCRIPTOR *>(buf);
|
||||
USB_FD_CONFIGURATION_DESCRIPTOR *ucd = reinterpret_cast<USB_FD_CONFIGURATION_DESCRIPTOR *>(buf);
|
||||
#endif
|
||||
|
||||
ei.address = addrPool.AllocAddress(parent, IsHub(ei.klass), port);
|
||||
@@ -415,9 +413,9 @@ again:
|
||||
HOST_DEBUG("configs: %i\r\n", configs);
|
||||
for(uint8_t conf = 0; (!rcode) && (conf < configs); conf++) {
|
||||
// read the config descriptor into a buffer.
|
||||
rcode = getConfDescr(ei.address, sizeof (USB_CONFIGURATION_DESCRIPTOR), conf, buf);
|
||||
rcode = getConfDescr(ei.address, sizeof (USB_FD_CONFIGURATION_DESCRIPTOR), conf, buf);
|
||||
if(rcode) {
|
||||
HOST_DEBUG("Configuring error: %2.2x Can't get USB_INTERFACE_DESCRIPTOR\r\n", rcode);
|
||||
HOST_DEBUG("Configuring error: %2.2x Can't get USB_FD_INTERFACE_DESCRIPTOR\r\n", rcode);
|
||||
rcode = UHS_HOST_ERROR_FailGetConfDescr;
|
||||
continue;
|
||||
}
|
||||
@@ -438,7 +436,7 @@ again:
|
||||
uint8_t offset;
|
||||
rcode = initDescrStream(&ei, ucd, pep, data, &left, &read, &offset);
|
||||
if(rcode) {
|
||||
HOST_DEBUG("Configuring error: %2.2x Can't get USB_INTERFACE_DESCRIPTOR stream.\r\n", rcode);
|
||||
HOST_DEBUG("Configuring error: %2.2x Can't get USB_FD_INTERFACE_DESCRIPTOR stream.\r\n", rcode);
|
||||
break;
|
||||
}
|
||||
for(; (numinf) && (!rcode); inf++) {
|
||||
@@ -451,7 +449,7 @@ again:
|
||||
break;
|
||||
}
|
||||
if(rcode) {
|
||||
HOST_DEBUG("Configuring error: %2.2x Can't close USB_INTERFACE_DESCRIPTOR stream.\r\n", rcode);
|
||||
HOST_DEBUG("Configuring error: %2.2x Can't close USB_FD_INTERFACE_DESCRIPTOR stream.\r\n", rcode);
|
||||
continue;
|
||||
}
|
||||
rcode = TestInterface(&ei);
|
||||
@@ -471,9 +469,9 @@ again:
|
||||
if(!bestsuccess) rcode = UHS_HOST_ERROR_DEVICE_NOT_SUPPORTED;
|
||||
}
|
||||
if(!rcode) {
|
||||
rcode = getConfDescr(ei.address, sizeof (USB_CONFIGURATION_DESCRIPTOR), bestconf, buf);
|
||||
rcode = getConfDescr(ei.address, sizeof (USB_FD_CONFIGURATION_DESCRIPTOR), bestconf, buf);
|
||||
if(rcode) {
|
||||
HOST_DEBUG("Configuring error: %2.2x Can't get USB_INTERFACE_DESCRIPTOR\r\n", rcode);
|
||||
HOST_DEBUG("Configuring error: %2.2x Can't get USB_FD_INTERFACE_DESCRIPTOR\r\n", rcode);
|
||||
rcode = UHS_HOST_ERROR_FailGetConfDescr;
|
||||
}
|
||||
}
|
||||
@@ -497,7 +495,7 @@ again:
|
||||
uint8_t offset;
|
||||
rcode = initDescrStream(&ei, ucd, pep, data, &left, &read, &offset);
|
||||
if(rcode) {
|
||||
HOST_DEBUG("Configuring error: %2.2x Can't get USB_INTERFACE_DESCRIPTOR stream.\r\n", rcode);
|
||||
HOST_DEBUG("Configuring error: %2.2x Can't get USB_FD_INTERFACE_DESCRIPTOR stream.\r\n", rcode);
|
||||
} else {
|
||||
for(; (numinf) && (!rcode); inf++) {
|
||||
// iterate for each interface on this config
|
||||
@@ -508,7 +506,7 @@ again:
|
||||
break;
|
||||
}
|
||||
if(rcode) {
|
||||
HOST_DEBUG("Configuring error: %2.2x Can't close USB_INTERFACE_DESCRIPTOR stream.\r\n", rcode);
|
||||
HOST_DEBUG("Configuring error: %2.2x Can't close USB_FD_INTERFACE_DESCRIPTOR stream.\r\n", rcode);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -596,7 +594,7 @@ void UHS_USB_HOST_BASE::ReleaseDevice(uint8_t addr) {
|
||||
* @param dataptr pointer to the data to return
|
||||
* @return status of the request, zero is success.
|
||||
*/
|
||||
uint8_t UHS_USB_HOST_BASE::getDevDescr(uint8_t addr, uint16_t nbytes, uint8_t* dataptr) {
|
||||
uint8_t UHS_USB_HOST_BASE::getDevDescr(uint8_t addr, uint16_t nbytes, uint8_t *dataptr) {
|
||||
return ( ctrlReq(addr, mkSETUP_PKT8(UHS_bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, 0x00, USB_DESCRIPTOR_DEVICE, 0x0000, nbytes), nbytes, dataptr));
|
||||
}
|
||||
|
||||
@@ -609,7 +607,7 @@ uint8_t UHS_USB_HOST_BASE::getDevDescr(uint8_t addr, uint16_t nbytes, uint8_t* d
|
||||
* @param dataptr ointer to the data to return
|
||||
* @return status of the request, zero is success.
|
||||
*/
|
||||
uint8_t UHS_USB_HOST_BASE::getConfDescr(uint8_t addr, uint16_t nbytes, uint8_t conf, uint8_t* dataptr) {
|
||||
uint8_t UHS_USB_HOST_BASE::getConfDescr(uint8_t addr, uint16_t nbytes, uint8_t conf, uint8_t *dataptr) {
|
||||
return ( ctrlReq(addr, mkSETUP_PKT8(UHS_bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, conf, USB_DESCRIPTOR_CONFIGURATION, 0x0000, nbytes), nbytes, dataptr));
|
||||
}
|
||||
|
||||
@@ -623,7 +621,7 @@ uint8_t UHS_USB_HOST_BASE::getConfDescr(uint8_t addr, uint16_t nbytes, uint8_t c
|
||||
* @param dataptr pointer to the data to return
|
||||
* @return status of the request, zero is success.
|
||||
*/
|
||||
uint8_t UHS_USB_HOST_BASE::getStrDescr(uint8_t addr, uint16_t ns, uint8_t index, uint16_t langid, uint8_t* dataptr) {
|
||||
uint8_t UHS_USB_HOST_BASE::getStrDescr(uint8_t addr, uint16_t ns, uint8_t index, uint16_t langid, uint8_t *dataptr) {
|
||||
return ( ctrlReq(addr, mkSETUP_PKT8(UHS_bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, index, USB_DESCRIPTOR_STRING, langid, ns), ns, dataptr));
|
||||
}
|
||||
|
||||
@@ -670,7 +668,7 @@ uint8_t UHS_USB_HOST_BASE::setConf(uint8_t addr, uint8_t conf_value) {
|
||||
* @param data pointer to buffer to hold transfer
|
||||
* @return zero for success or error code
|
||||
*/
|
||||
uint8_t UHS_USB_HOST_BASE::outTransfer(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t* data) {
|
||||
uint8_t UHS_USB_HOST_BASE::outTransfer(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t *data) {
|
||||
UHS_EpInfo *pep = NULL;
|
||||
uint16_t nak_limit = 0;
|
||||
HOST_DEBUG("outTransfer: addr: 0x%2.2x ep: 0x%2.2x nbytes: 0x%4.4x data: 0x%p\r\n", addr, ep, nbytes, data);
|
||||
@@ -691,7 +689,7 @@ uint8_t UHS_USB_HOST_BASE::outTransfer(uint8_t addr, uint8_t ep, uint16_t nbytes
|
||||
* @param data pointer to buffer to hold transfer
|
||||
* @return zero for success or error code
|
||||
*/
|
||||
uint8_t UHS_USB_HOST_BASE::inTransfer(uint8_t addr, uint8_t ep, uint16_t *nbytesptr, uint8_t* data) {
|
||||
uint8_t UHS_USB_HOST_BASE::inTransfer(uint8_t addr, uint8_t ep, uint16_t *nbytesptr, uint8_t *data) {
|
||||
UHS_EpInfo *pep = NULL;
|
||||
uint16_t nak_limit = 0;
|
||||
|
||||
@@ -721,7 +719,7 @@ uint8_t UHS_USB_HOST_BASE::inTransfer(uint8_t addr, uint8_t ep, uint16_t *nbytes
|
||||
* @param offset
|
||||
* @return zero for success or error code
|
||||
*/
|
||||
uint8_t UHS_USB_HOST_BASE::initDescrStream(ENUMERATION_INFO *ei, USB_CONFIGURATION_DESCRIPTOR *ucd, UHS_EpInfo *pep, uint8_t *data, uint16_t *left, uint16_t *read, uint8_t *offset) {
|
||||
uint8_t UHS_USB_HOST_BASE::initDescrStream(ENUMERATION_INFO *ei, USB_FD_CONFIGURATION_DESCRIPTOR *ucd, UHS_EpInfo *pep, uint8_t *data, uint16_t *left, uint16_t *read, uint8_t *offset) {
|
||||
if(!ei || !ucd) return UHS_HOST_ERROR_BAD_ARGUMENT;
|
||||
if(!pep) return UHS_HOST_ERROR_NULL_EPINFO;
|
||||
*left = ucd->wTotalLength;
|
||||
@@ -837,7 +835,7 @@ uint8_t UHS_USB_HOST_BASE::getNextInterface(ENUMERATION_INFO *ei, UHS_EpInfo *pe
|
||||
return rcode;
|
||||
}
|
||||
|
||||
uint8_t UHS_USB_HOST_BASE::seekInterface(ENUMERATION_INFO *ei, uint16_t inf, USB_CONFIGURATION_DESCRIPTOR *ucd) {
|
||||
uint8_t UHS_USB_HOST_BASE::seekInterface(ENUMERATION_INFO *ei, uint16_t inf, USB_FD_CONFIGURATION_DESCRIPTOR *ucd) {
|
||||
if(!ei || !ucd) return UHS_HOST_ERROR_BAD_ARGUMENT;
|
||||
uint8_t data[ei->bMaxPacketSize0];
|
||||
UHS_EpInfo *pep;
|
||||
@@ -982,11 +980,11 @@ uint8_t UHS_USB_HOST_BASE::eat(UHS_EpInfo *pep, uint16_t *left, uint16_t *read,
|
||||
return rcode;
|
||||
}
|
||||
|
||||
uint8_t UHS_USB_HOST_BASE::ctrlReq(uint8_t addr, uint64_t Request, uint16_t nbytes, uint8_t* dataptr) {
|
||||
uint8_t UHS_USB_HOST_BASE::ctrlReq(uint8_t addr, uint64_t Request, uint16_t nbytes, uint8_t *dataptr) {
|
||||
//bool direction = bmReqType & 0x80; //request direction, IN or OUT
|
||||
uint8_t rcode = 0;
|
||||
|
||||
// Serial.println("");
|
||||
//Serial.println();
|
||||
UHS_EpInfo *pep = ctrlReqOpen(addr, Request, dataptr);
|
||||
if(!pep) {
|
||||
HOST_DEBUG("ctrlReq1: ERROR_NULL_EPINFO addr: %d\r\n", addr);
|
||||
@@ -1007,7 +1005,7 @@ uint8_t UHS_USB_HOST_BASE::ctrlReq(uint8_t addr, uint64_t Request, uint16_t nbyt
|
||||
rcode = ctrlReqRead(pep, &left, &read, nbytes, dataptr);
|
||||
|
||||
#if UHS_DEVICE_WINDOWS_USB_SPEC_VIOLATION_DESCRIPTOR_DEVICE
|
||||
HOST_DEBUG("RESULT: 0x%2.2x 0x%2.2x 0x%2.2x 0x%8.8lx%8.8lx\r\n", rcode, addr, read, (uint32_t)((Request>>32)&0xfffffffflu), (uint32_t)(Request&0xfffffffflu));
|
||||
HOST_DEBUG("RESULT: 0x%2.2x 0x%2.2x 0x%2.2x 0x%8.8lx%8.8lx\r\n", rcode, addr, read, (uint32_t)((Request>>32)&0xFFFFFFFFLU), (uint32_t)(Request&0xFFFFFFFFLU));
|
||||
// Should only be used for GET_DESCRIPTOR USB_DESCRIPTOR_DEVICE
|
||||
constexpr uint32_t req_match = ((uint32_t)USB_DESCRIPTOR_DEVICE << 24) |
|
||||
((uint32_t)USB_REQUEST_GET_DESCRIPTOR << 8);
|
||||
|
186
Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_macros.h
Executable file → Normal file
186
Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_macros.h
Executable file → Normal file
@@ -20,7 +20,7 @@ Contact information
|
||||
-------------------
|
||||
|
||||
Circuits At Home, LTD
|
||||
Web : http://www.circuitsathome.com
|
||||
Web : https://www.circuitsathome.com
|
||||
e-mail : support@circuitsathome.com
|
||||
*/
|
||||
|
||||
@@ -144,175 +144,13 @@ e-mail : support@circuitsathome.com
|
||||
#define UHS_GET_DPI(x) (x)
|
||||
#endif
|
||||
|
||||
#ifndef __AVR__
|
||||
#ifndef __PGMSPACE_H_
|
||||
// This define should prevent reading the system pgmspace.h if included elsewhere
|
||||
// This is not normally needed.
|
||||
#define __PGMSPACE_H_ 1
|
||||
#endif
|
||||
|
||||
#ifndef PROGMEM
|
||||
#define PROGMEM
|
||||
#endif
|
||||
#ifndef PGM_P
|
||||
#define PGM_P const char *
|
||||
#endif
|
||||
#ifndef PSTR
|
||||
#define PSTR(str) (str)
|
||||
#endif
|
||||
#ifndef F
|
||||
#define F(str) (str)
|
||||
#endif
|
||||
#ifndef _SFR_BYTE
|
||||
#define _SFR_BYTE(n) (n)
|
||||
#endif
|
||||
#ifndef memchr_P
|
||||
#define memchr_P(str, c, len) memchr((str), (c), (len))
|
||||
#endif
|
||||
#ifndef memcmp_P
|
||||
#define memcmp_P(a, b, n) memcmp((a), (b), (n))
|
||||
#endif
|
||||
#ifndef memcpy_P
|
||||
#define memcpy_P(dest, src, num) memcpy((dest), (src), (num))
|
||||
#endif
|
||||
#ifndef memmem_P
|
||||
#define memmem_P(a, alen, b, blen) memmem((a), (alen), (b), (blen))
|
||||
#endif
|
||||
#ifndef memrchr_P
|
||||
#define memrchr_P(str, val, len) memrchr((str), (val), (len))
|
||||
#endif
|
||||
#ifndef strcat_P
|
||||
#define strcat_P(dest, src) strcat((dest), (src))
|
||||
#endif
|
||||
#ifndef strchr_P
|
||||
#define strchr_P(str, c) strchr((str), (c))
|
||||
#endif
|
||||
#ifndef strchrnul_P
|
||||
#define strchrnul_P(str, c) strchrnul((str), (c))
|
||||
#endif
|
||||
#ifndef strcmp_P
|
||||
#define strcmp_P(a, b) strcmp((a), (b))
|
||||
#endif
|
||||
#ifndef strcpy_P
|
||||
#define strcpy_P(dest, src) strcpy((dest), (src))
|
||||
#endif
|
||||
#ifndef strcasecmp_P
|
||||
#define strcasecmp_P(a, b) strcasecmp((a), (b))
|
||||
#endif
|
||||
#ifndef strcasestr_P
|
||||
#define strcasestr_P(a, b) strcasestr((a), (b))
|
||||
#endif
|
||||
#ifndef strlcat_P
|
||||
#define strlcat_P(dest, src, len) strlcat((dest), (src), (len))
|
||||
#endif
|
||||
#ifndef strlcpy_P
|
||||
#define strlcpy_P(dest, src, len) strlcpy((dest), (src), (len))
|
||||
#endif
|
||||
#ifndef strlen_P
|
||||
#define strlen_P(s) strlen((const char *)(s))
|
||||
#endif
|
||||
#ifndef strnlen_P
|
||||
#define strnlen_P(str, len) strnlen((str), (len))
|
||||
#endif
|
||||
#ifndef strncmp_P
|
||||
#define strncmp_P(a, b, n) strncmp((a), (b), (n))
|
||||
#endif
|
||||
#ifndef strncasecmp_P
|
||||
#define strncasecmp_P(a, b, n) strncasecmp((a), (b), (n))
|
||||
#endif
|
||||
#ifndef strncat_P
|
||||
#define strncat_P(a, b, n) strncat((a), (b), (n))
|
||||
#endif
|
||||
#ifndef strncpy_P
|
||||
#define strncpy_P(a, b, n) strncmp((a), (b), (n))
|
||||
#endif
|
||||
#ifndef strpbrk_P
|
||||
#define strpbrk_P(str, chrs) strpbrk((str), (chrs))
|
||||
#endif
|
||||
#ifndef strrchr_P
|
||||
#define strrchr_P(str, c) strrchr((str), (c))
|
||||
#endif
|
||||
#ifndef strsep_P
|
||||
#define strsep_P(strp, delim) strsep((strp), (delim))
|
||||
#endif
|
||||
#ifndef strspn_P
|
||||
#define strspn_P(str, chrs) strspn((str), (chrs))
|
||||
#endif
|
||||
#ifndef strstr_P
|
||||
#define strstr_P(a, b) strstr((a), (b))
|
||||
#endif
|
||||
#ifndef sprintf_P
|
||||
#define sprintf_P(s, ...) sprintf((s), __VA_ARGS__)
|
||||
#endif
|
||||
#ifndef vfprintf_P
|
||||
#define vfprintf_P(s, ...) vfprintf((s), __VA_ARGS__)
|
||||
#endif
|
||||
#ifndef printf_P
|
||||
#define printf_P(...) printf(__VA_ARGS__)
|
||||
#endif
|
||||
#ifndef snprintf_P
|
||||
#define snprintf_P(s, n, ...) ((s), (n), __VA_ARGS__)
|
||||
#endif
|
||||
#ifndef vsprintf_P
|
||||
#define vsprintf_P(s, ...) ((s),__VA_ARGS__)
|
||||
#endif
|
||||
#ifndef vsnprintf_P
|
||||
#define vsnprintf_P(s, n, ...) ((s), (n),__VA_ARGS__)
|
||||
#endif
|
||||
#ifndef fprintf_P
|
||||
#define fprintf_P(s, ...) ((s), __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#ifndef pgm_read_byte
|
||||
#define pgm_read_byte(addr) (*(const unsigned char *)(addr))
|
||||
#endif
|
||||
#ifndef pgm_read_word
|
||||
#define pgm_read_word(addr) (*(const unsigned short *)(addr))
|
||||
#endif
|
||||
#ifndef pgm_read_dword
|
||||
#define pgm_read_dword(addr) (*(const unsigned long *)(addr))
|
||||
#endif
|
||||
#ifndef pgm_read_float
|
||||
#define pgm_read_float(addr) (*(const float *)(addr))
|
||||
#endif
|
||||
|
||||
#ifndef pgm_read_byte_near
|
||||
#define pgm_read_byte_near(addr) pgm_read_byte(addr)
|
||||
#endif
|
||||
#ifndef pgm_read_word_near
|
||||
#define pgm_read_word_near(addr) pgm_read_word(addr)
|
||||
#endif
|
||||
#ifndef pgm_read_dword_near
|
||||
#define pgm_read_dword_near(addr) pgm_read_dword(addr)
|
||||
#endif
|
||||
#ifndef pgm_read_float_near
|
||||
#define pgm_read_float_near(addr) pgm_read_float(addr)
|
||||
#endif
|
||||
#ifndef pgm_read_byte_far
|
||||
#define pgm_read_byte_far(addr) pgm_read_byte(addr)
|
||||
#endif
|
||||
#ifndef pgm_read_word_far
|
||||
#define pgm_read_word_far(addr) pgm_read_word(addr)
|
||||
#endif
|
||||
#ifndef pgm_read_dword_far
|
||||
#define pgm_read_dword_far(addr) pgm_read_dword(addr)
|
||||
#endif
|
||||
#ifndef pgm_read_float_far
|
||||
#define pgm_read_float_far(addr) pgm_read_float(addr)
|
||||
#endif
|
||||
|
||||
#ifndef pgm_read_pointer
|
||||
#define pgm_read_pointer
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#include "../../../../HAL/shared/progmem.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// HANDY MACROS
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Atmoically set/clear single bits using bitbands.
|
||||
// Atomically set/clear single bits using bitbands.
|
||||
// Believe it or not, this boils down to a constant,
|
||||
// and is less code than using |= &= operators.
|
||||
// Bonus, it makes code easier to read too.
|
||||
@@ -343,16 +181,16 @@ e-mail : support@circuitsathome.com
|
||||
#define UHS_UINT8_BYTE7(__usi__) (((uint8_t *)&(__usi__))[7])
|
||||
#else
|
||||
// Note: The cast alone to uint8_t is actually enough.
|
||||
// GCC throws out the "& 0xff", and the size is no different.
|
||||
// GCC throws out the "& 0xFF", and the size is no different.
|
||||
// Some compilers need it.
|
||||
#define UHS_UINT8_BYTE0(__usi__) ((uint8_t)((__usi__) & 0xff ))
|
||||
#define UHS_UINT8_BYTE1(__usi__) ((uint8_t)(((__usi__) >> 8) & 0xff))
|
||||
#define UHS_UINT8_BYTE2(__usi__) ((uint8_t)(((__usi__) >> 16) & 0xff))
|
||||
#define UHS_UINT8_BYTE3(__usi__) ((uint8_t)(((__usi__) >> 24) & 0xff))
|
||||
#define UHS_UINT8_BYTE4(__usi__) ((uint8_t)(((__usi__) >> 32) & 0xff))
|
||||
#define UHS_UINT8_BYTE5(__usi__) ((uint8_t)(((__usi__) >> 40) & 0xff))
|
||||
#define UHS_UINT8_BYTE6(__usi__) ((uint8_t)(((__usi__) >> 48) & 0xff))
|
||||
#define UHS_UINT8_BYTE7(__usi__) ((uint8_t)(((__usi__) >> 56) & 0xff))
|
||||
#define UHS_UINT8_BYTE0(__usi__) ((uint8_t)((__usi__) & 0xFF ))
|
||||
#define UHS_UINT8_BYTE1(__usi__) ((uint8_t)(((__usi__) >> 8) & 0xFF))
|
||||
#define UHS_UINT8_BYTE2(__usi__) ((uint8_t)(((__usi__) >> 16) & 0xFF))
|
||||
#define UHS_UINT8_BYTE3(__usi__) ((uint8_t)(((__usi__) >> 24) & 0xFF))
|
||||
#define UHS_UINT8_BYTE4(__usi__) ((uint8_t)(((__usi__) >> 32) & 0xFF))
|
||||
#define UHS_UINT8_BYTE5(__usi__) ((uint8_t)(((__usi__) >> 40) & 0xFF))
|
||||
#define UHS_UINT8_BYTE6(__usi__) ((uint8_t)(((__usi__) >> 48) & 0xFF))
|
||||
#define UHS_UINT8_BYTE7(__usi__) ((uint8_t)(((__usi__) >> 56) & 0xFF))
|
||||
#endif
|
||||
#define UHS_UINT16_SET_BYTE1(__usi__) ((uint16_t)(__usi__) << 8)
|
||||
#define UHS_UINT32_SET_BYTE1(__usi__) ((uint32_t)(__usi__) << 8)
|
||||
|
2
Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_message.h
Executable file → Normal file
2
Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_message.h
Executable file → Normal file
@@ -20,7 +20,7 @@ Contact information
|
||||
-------------------
|
||||
|
||||
Circuits At Home, LTD
|
||||
Web : http://www.circuitsathome.com
|
||||
Web : https://www.circuitsathome.com
|
||||
e-mail : support@circuitsathome.com
|
||||
*/
|
||||
#if !defined(_UHS_host_h_) || defined(__MESSAGE_H__)
|
||||
|
2
Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_printf_HELPER.h
Executable file → Normal file
2
Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_printf_HELPER.h
Executable file → Normal file
@@ -20,7 +20,7 @@ Contact information
|
||||
-------------------
|
||||
|
||||
Circuits At Home, LTD
|
||||
Web : http://www.circuitsathome.com
|
||||
Web : https://www.circuitsathome.com
|
||||
e-mail : support@circuitsathome.com
|
||||
*/
|
||||
|
||||
|
14
Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_printhex.h
Executable file → Normal file
14
Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_printhex.h
Executable file → Normal file
@@ -20,7 +20,7 @@ Contact information
|
||||
-------------------
|
||||
|
||||
Circuits At Home, LTD
|
||||
Web : http://www.circuitsathome.com
|
||||
Web : https://www.circuitsathome.com
|
||||
e-mail : support@circuitsathome.com
|
||||
*/
|
||||
|
||||
@@ -33,13 +33,13 @@ void E_Notifyc(char c, int lvl);
|
||||
|
||||
template <class T>
|
||||
void PrintHex(T val, int lvl) {
|
||||
int num_nibbles = sizeof (T) * 2;
|
||||
int num_nybbles = sizeof (T) * 2;
|
||||
|
||||
do {
|
||||
char v = 48 + (((val >> (num_nibbles - 1) * 4)) & 0x0f);
|
||||
char v = 48 + (((val >> (num_nybbles - 1) * 4)) & 0x0F);
|
||||
if(v > 57) v += 7;
|
||||
E_Notifyc(v, lvl);
|
||||
} while(--num_nibbles);
|
||||
} while(--num_nybbles);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
@@ -53,13 +53,13 @@ void PrintBin(T val, int lvl) {
|
||||
|
||||
template <class T>
|
||||
void SerialPrintHex(T val) {
|
||||
int num_nibbles = sizeof (T) * 2;
|
||||
int num_nybbles = sizeof (T) * 2;
|
||||
|
||||
do {
|
||||
char v = 48 + (((val >> (num_nibbles - 1) * 4)) & 0x0f);
|
||||
char v = 48 + (((val >> (num_nybbles - 1) * 4)) & 0x0F);
|
||||
if(v > 57) v += 7;
|
||||
USB_HOST_SERIAL.print(v);
|
||||
} while(--num_nibbles);
|
||||
} while(--num_nybbles);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
|
4
Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_settings.h
Executable file → Normal file
4
Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_settings.h
Executable file → Normal file
@@ -20,7 +20,7 @@ Contact information
|
||||
-------------------
|
||||
|
||||
Circuits At Home, LTD
|
||||
Web : http://www.circuitsathome.com
|
||||
Web : https://www.circuitsathome.com
|
||||
e-mail : support@circuitsathome.com
|
||||
*/
|
||||
|
||||
@@ -115,7 +115,7 @@ e-mail : support@circuitsathome.com
|
||||
#if GCC_VERSION < 40602 // Test for GCC < 4.6.2
|
||||
#ifdef PROGMEM
|
||||
#undef PROGMEM
|
||||
#define PROGMEM __attribute__((section(".progmem.data"))) // Workaround for http://gcc.gnu.org/bugzilla/show_bug.cgi?id=34734#c4
|
||||
#define PROGMEM __attribute__((section(".progmem.data"))) // Workaround for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=34734#c4
|
||||
#ifdef PSTR
|
||||
#undef PSTR
|
||||
#define PSTR(s) (__extension__({static const char __c[] PROGMEM = (s); &__c[0];})) // Copied from pgmspace.h in avr-libc source
|
||||
|
22
Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_usb_ch9.h
Executable file → Normal file
22
Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_usb_ch9.h
Executable file → Normal file
@@ -20,7 +20,7 @@ Contact information
|
||||
-------------------
|
||||
|
||||
Circuits At Home, LTD
|
||||
Web : http://www.circuitsathome.com
|
||||
Web : https://www.circuitsathome.com
|
||||
e-mail : support@circuitsathome.com
|
||||
*/
|
||||
|
||||
@@ -108,12 +108,12 @@ e-mail : support@circuitsathome.com
|
||||
#define USB_DESCRIPTOR_OTHER_SPEED 0x07 // bDescriptorType for a Other Speed Configuration.
|
||||
#define USB_DESCRIPTOR_INTERFACE_POWER 0x08 // bDescriptorType for Interface Power.
|
||||
#define USB_DESCRIPTOR_OTG 0x09 // bDescriptorType for an OTG Descriptor.
|
||||
#define USB_DESCRIPTOR_DEBUG 0x0a
|
||||
#define USB_DESCRIPTOR_INTERFACE_ASSOCIATION 0x0b
|
||||
#define USB_DESCRIPTOR_SECURITY 0x0c
|
||||
#define USB_DESCRIPTOR_KEY 0x0d
|
||||
#define USB_DESCRIPTOR_ENCRYPTION_TYPE 0x0e
|
||||
#define USB_DESCRIPTOR_BOS 0x0f
|
||||
#define USB_DESCRIPTOR_DEBUG 0x0A
|
||||
#define USB_DESCRIPTOR_INTERFACE_ASSOCIATION 0x0B
|
||||
#define USB_DESCRIPTOR_SECURITY 0x0C
|
||||
#define USB_DESCRIPTOR_KEY 0x0D
|
||||
#define USB_DESCRIPTOR_ENCRYPTION_TYPE 0x0E
|
||||
#define USB_DESCRIPTOR_BOS 0x0F
|
||||
#define USB_DESCRIPTOR_DEVICE_CAPABILITY 0x10
|
||||
#define USB_DESCRIPTOR_WIRELESS_ENDPOINT_COMP 0x11
|
||||
#define USB_DESCRIPTOR_WIRE_ADAPTER 0x21
|
||||
@@ -164,7 +164,7 @@ typedef struct {
|
||||
uint8_t iProduct; // Index of String Descriptor describing the product.
|
||||
uint8_t iSerialNumber; // Index of String Descriptor with the device's serial number.
|
||||
uint8_t bNumConfigurations; // Number of possible configurations.
|
||||
} __attribute__((packed)) USB_DEVICE_DESCRIPTOR;
|
||||
} __attribute__((packed)) USB_FD_DEVICE_DESCRIPTOR;
|
||||
|
||||
/* Configuration descriptor structure */
|
||||
typedef struct {
|
||||
@@ -176,7 +176,7 @@ typedef struct {
|
||||
uint8_t iConfiguration; // Index of String Descriptor describing the configuration.
|
||||
uint8_t bmAttributes; // Configuration characteristics.
|
||||
uint8_t bMaxPower; // Maximum power consumed by this configuration.
|
||||
} __attribute__((packed)) USB_CONFIGURATION_DESCRIPTOR;
|
||||
} __attribute__((packed)) USB_FD_CONFIGURATION_DESCRIPTOR;
|
||||
|
||||
/* Interface descriptor structure */
|
||||
typedef struct {
|
||||
@@ -189,7 +189,7 @@ typedef struct {
|
||||
uint8_t bInterfaceSubClass; // Subclass code (assigned by the USB-IF).
|
||||
uint8_t bInterfaceProtocol; // Protocol code (assigned by the USB-IF). 0xFF-Vendor specific.
|
||||
uint8_t iInterface; // Index of String Descriptor describing the interface.
|
||||
} __attribute__((packed)) USB_INTERFACE_DESCRIPTOR;
|
||||
} __attribute__((packed)) USB_FD_INTERFACE_DESCRIPTOR;
|
||||
|
||||
/* Endpoint descriptor structure */
|
||||
typedef struct {
|
||||
@@ -199,7 +199,7 @@ typedef struct {
|
||||
uint8_t bmAttributes; // Endpoint transfer type.
|
||||
uint16_t wMaxPacketSize; // Maximum packet size.
|
||||
uint8_t bInterval; // Polling interval in frames.
|
||||
} __attribute__((packed)) USB_ENDPOINT_DESCRIPTOR;
|
||||
} __attribute__((packed)) USB_FD_ENDPOINT_DESCRIPTOR;
|
||||
|
||||
/* HID descriptor */
|
||||
/*
|
||||
|
23
Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_usbhost.h
Executable file → Normal file
23
Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_usbhost.h
Executable file → Normal file
@@ -20,7 +20,7 @@ Contact information
|
||||
-------------------
|
||||
|
||||
Circuits At Home, LTD
|
||||
Web : http://www.circuitsathome.com
|
||||
Web : https://www.circuitsathome.com
|
||||
e-mail : support@circuitsathome.com
|
||||
*/
|
||||
|
||||
@@ -103,7 +103,7 @@ public:
|
||||
return (current_state == usb_task_state);
|
||||
};
|
||||
|
||||
virtual UHS_EpInfo * UHS_NI ctrlReqOpen(NOTUSED(uint8_t addr), NOTUSED(uint64_t Request), NOTUSED(uint8_t* dataptr)) {
|
||||
virtual UHS_EpInfo * UHS_NI ctrlReqOpen(NOTUSED(uint8_t addr), NOTUSED(uint64_t Request), NOTUSED(uint8_t *dataptr)) {
|
||||
return NULL;
|
||||
};
|
||||
|
||||
@@ -207,23 +207,23 @@ public:
|
||||
interrupts();
|
||||
}
|
||||
|
||||
uint8_t UHS_NI seekInterface(ENUMERATION_INFO *ei, uint16_t inf, USB_CONFIGURATION_DESCRIPTOR *ucd);
|
||||
uint8_t UHS_NI seekInterface(ENUMERATION_INFO *ei, uint16_t inf, USB_FD_CONFIGURATION_DESCRIPTOR *ucd);
|
||||
|
||||
uint8_t UHS_NI setEpInfoEntry(uint8_t addr, uint8_t iface, uint8_t epcount, volatile UHS_EpInfo* eprecord_ptr);
|
||||
|
||||
uint8_t UHS_NI EPClearHalt(uint8_t addr, uint8_t ep);
|
||||
|
||||
uint8_t UHS_NI ctrlReq(uint8_t addr, uint64_t Request, uint16_t nbytes, uint8_t* dataptr);
|
||||
uint8_t UHS_NI ctrlReq(uint8_t addr, uint64_t Request, uint16_t nbytes, uint8_t *dataptr);
|
||||
|
||||
uint8_t UHS_NI getDevDescr(uint8_t addr, uint16_t nbytes, uint8_t* dataptr);
|
||||
uint8_t UHS_NI getDevDescr(uint8_t addr, uint16_t nbytes, uint8_t *dataptr);
|
||||
|
||||
uint8_t UHS_NI getConfDescr(uint8_t addr, uint16_t nbytes, uint8_t conf, uint8_t* dataptr);
|
||||
uint8_t UHS_NI getConfDescr(uint8_t addr, uint16_t nbytes, uint8_t conf, uint8_t *dataptr);
|
||||
|
||||
uint8_t UHS_NI setAddr(uint8_t oldaddr, uint8_t newaddr);
|
||||
|
||||
uint8_t UHS_NI setConf(uint8_t addr, uint8_t conf_value);
|
||||
|
||||
uint8_t UHS_NI getStrDescr(uint8_t addr, uint16_t nbytes, uint8_t index, uint16_t langid, uint8_t* dataptr);
|
||||
uint8_t UHS_NI getStrDescr(uint8_t addr, uint16_t nbytes, uint8_t index, uint16_t langid, uint8_t *dataptr);
|
||||
|
||||
void UHS_NI ReleaseDevice(uint8_t addr);
|
||||
|
||||
@@ -261,9 +261,9 @@ public:
|
||||
uint8_t TestInterface(ENUMERATION_INFO *ei);
|
||||
uint8_t enumerateInterface(ENUMERATION_INFO *ei);
|
||||
uint8_t getNextInterface(ENUMERATION_INFO *ei, UHS_EpInfo *pep, uint8_t data[], uint16_t *left, uint16_t *read, uint8_t *offset);
|
||||
uint8_t initDescrStream(ENUMERATION_INFO *ei, USB_CONFIGURATION_DESCRIPTOR *ucd, UHS_EpInfo *pep, uint8_t *data, uint16_t *left, uint16_t *read, uint8_t *offset);
|
||||
uint8_t outTransfer(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t* data);
|
||||
uint8_t inTransfer(uint8_t addr, uint8_t ep, uint16_t *nbytesptr, uint8_t* data);
|
||||
uint8_t initDescrStream(ENUMERATION_INFO *ei, USB_FD_CONFIGURATION_DESCRIPTOR *ucd, UHS_EpInfo *pep, uint8_t *data, uint16_t *left, uint16_t *read, uint8_t *offset);
|
||||
uint8_t outTransfer(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t *data);
|
||||
uint8_t inTransfer(uint8_t addr, uint8_t ep, uint16_t *nbytesptr, uint8_t *data);
|
||||
uint8_t doSoftReset(uint8_t parent, uint8_t port, uint8_t address);
|
||||
uint8_t getone(UHS_EpInfo *pep, uint16_t *left, uint16_t *read, uint8_t *dataptr, uint8_t *offset);
|
||||
uint8_t eat(UHS_EpInfo *pep, uint16_t *left, uint16_t *read, uint8_t *dataptr, uint8_t *offset, uint16_t *yum);
|
||||
@@ -350,7 +350,6 @@ public:
|
||||
|
||||
/**
|
||||
* Executed before anything else in Release().
|
||||
*
|
||||
*/
|
||||
virtual void OnRelease() {
|
||||
return;
|
||||
@@ -403,7 +402,6 @@ public:
|
||||
|
||||
#if 0
|
||||
/**
|
||||
*
|
||||
* @return true if this interface is Vendor Specific.
|
||||
*/
|
||||
virtual bool IsVSI() {
|
||||
@@ -414,7 +412,6 @@ public:
|
||||
|
||||
#if 0
|
||||
/**
|
||||
*
|
||||
* Vendor Specific interface class.
|
||||
* This is used by a partner interface.
|
||||
* It can also be used to force-enumerate an interface that
|
||||
|
2
Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_util_INLINE.h
Executable file → Normal file
2
Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/UHS_util_INLINE.h
Executable file → Normal file
@@ -20,7 +20,7 @@ Contact information
|
||||
-------------------
|
||||
|
||||
Circuits At Home, LTD
|
||||
Web : http://www.circuitsathome.com
|
||||
Web : https://www.circuitsathome.com
|
||||
e-mail : support@circuitsathome.com
|
||||
*/
|
||||
|
||||
|
40
Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/USB_HOST_SHIELD/UHS_max3421e.h
Executable file → Normal file
40
Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/USB_HOST_SHIELD/UHS_max3421e.h
Executable file → Normal file
@@ -13,7 +13,7 @@ Contact information
|
||||
-------------------
|
||||
|
||||
Circuits At Home, LTD
|
||||
Web : http://www.circuitsathome.com
|
||||
Web : https://www.circuitsathome.com
|
||||
e-mail : support@circuitsathome.com
|
||||
*/
|
||||
#if !defined(USB_HOST_SHIELD_H) || defined(_max3421e_h_)
|
||||
@@ -59,19 +59,19 @@ e-mail : support@circuitsathome.com
|
||||
|
||||
// (CPUCTL)
|
||||
#define rCPUCTL 0x80 //16<<3
|
||||
#define bmPUSLEWID1 0x80 //b7
|
||||
#define bmPULSEWID1 0x80 //b7
|
||||
#define bmPULSEWID0 0x40 //b6
|
||||
#define bmIE 0x01 //b0
|
||||
|
||||
// bmPUSLEWID1 bmPULSEWID0 Pulse width
|
||||
// bmPULSEWID1 bmPULSEWID0 Pulse width
|
||||
// 0 0 10.6uS
|
||||
// 0 1 5.3uS
|
||||
// 1 0 2.6uS
|
||||
// 1 1 1.3uS
|
||||
#define PUSLEWIDTH10_6 (0)
|
||||
#define PUSLEWIDTH5_3 (bmPULSEWID0)
|
||||
#define PUSLEWIDTH2_6 (bmPUSLEWID1)
|
||||
#define PUSLEWIDTH1_3 (bmPULSEWID0 | bmPUSLEWID1)
|
||||
#define PULSEWIDTH10_6 (0)
|
||||
#define PULSEWIDTH5_3 (bmPULSEWID0)
|
||||
#define PULSEWIDTH2_6 (bmPULSEWID1)
|
||||
#define PULSEWIDTH1_3 (bmPULSEWID0 | bmPULSEWID1)
|
||||
|
||||
// (PINCTL)
|
||||
#define rPINCTL 0x88 //17<<3
|
||||
@@ -90,7 +90,7 @@ e-mail : support@circuitsathome.com
|
||||
#define rREVISION 0x90 //18<<3
|
||||
|
||||
// (IOPINS1)
|
||||
#define rIOPINS1 0xa0 //20<<3
|
||||
#define rIOPINS1 0xA0 //20<<3
|
||||
#define bmGPOUT0 0x01 //
|
||||
#define bmGPOUT1 0x02 //
|
||||
#define bmGPOUT2 0x04 //
|
||||
@@ -101,7 +101,7 @@ e-mail : support@circuitsathome.com
|
||||
#define bmGPIN3 0x80 //
|
||||
|
||||
// (IOPINS2)
|
||||
#define rIOPINS2 0xa8 //21<<3
|
||||
#define rIOPINS2 0xA8 //21<<3
|
||||
#define bmGPOUT4 0x01 //
|
||||
#define bmGPOUT5 0x02 //
|
||||
#define bmGPOUT6 0x04 //
|
||||
@@ -112,7 +112,7 @@ e-mail : support@circuitsathome.com
|
||||
#define bmGPIN7 0x80 //
|
||||
|
||||
// (GPINIRQ)
|
||||
#define rGPINIRQ 0xb0 //22<<3
|
||||
#define rGPINIRQ 0xB0 //22<<3
|
||||
#define bmGPINIRQ0 0x01 //
|
||||
#define bmGPINIRQ1 0x02 //
|
||||
#define bmGPINIRQ2 0x04 //
|
||||
@@ -123,7 +123,7 @@ e-mail : support@circuitsathome.com
|
||||
#define bmGPINIRQ7 0x80 //
|
||||
|
||||
// (GPINIEN)
|
||||
#define rGPINIEN 0xb8 //23<<3
|
||||
#define rGPINIEN 0xB8 //23<<3
|
||||
#define bmGPINIEN0 0x01 //
|
||||
#define bmGPINIEN1 0x02 //
|
||||
#define bmGPINIEN2 0x04 //
|
||||
@@ -134,7 +134,7 @@ e-mail : support@circuitsathome.com
|
||||
#define bmGPINIEN7 0x80 //
|
||||
|
||||
// (GPINPOL)
|
||||
#define rGPINPOL 0xc0 //24<<3
|
||||
#define rGPINPOL 0xC0 //24<<3
|
||||
#define bmGPINPOL0 0x01 //
|
||||
#define bmGPINPOL1 0x02 //
|
||||
#define bmGPINPOL2 0x04 //
|
||||
@@ -151,7 +151,7 @@ e-mail : support@circuitsathome.com
|
||||
// The CPU should never directly clear the SNDBAVIRQ bit.
|
||||
|
||||
// Host Interrupt Request Status (HIRQ)
|
||||
#define rHIRQ 0xc8 // Host Interrupt Request Register
|
||||
#define rHIRQ 0xC8 // Host Interrupt Request Register
|
||||
#define bmBUSEVENTIRQ 0x01 // BUS Reset Done or BUS Resume Interrupt Request
|
||||
#define bmRWUIRQ 0x02 // Remote Wakeup Interrupt Request
|
||||
#define bmRCVDAVIRQ 0x04 // Receive FIFO Data Available Interrupt Request
|
||||
@@ -165,7 +165,7 @@ e-mail : support@circuitsathome.com
|
||||
#define ICLRALLBITS (bmBUSEVENTIRQ | bmRWUIRQ | bmRCVDAVIRQ | bmSUSDNIRQ | bmCONDETIRQ | bmFRAMEIRQ | bmHXFRDNIRQ)
|
||||
|
||||
// Host Interrupt Request Control (HIEN)
|
||||
#define rHIEN 0xd0 //
|
||||
#define rHIEN 0xD0 //
|
||||
#define bmBUSEVENTIE bmBUSEVENTIRQ // BUS Reset Done or BUS Resume Interrupt Request Enable
|
||||
#define bmRWUIE bmRWUIRQ // Remote Wakeup Interrupt Request Enable
|
||||
#define bmRCVDAVIE bmRCVDAVIRQ // Receive FIFO Data Available Interrupt Request Enable
|
||||
@@ -176,7 +176,7 @@ e-mail : support@circuitsathome.com
|
||||
#define bmHXFRDNIE bmHXFRDNIRQ // Host Transfer Done Interrupt Request Enable
|
||||
|
||||
// (MODE))
|
||||
#define rMODE 0xd8 //27<<3
|
||||
#define rMODE 0xD8 //27<<3
|
||||
#define bmHOST 0x01 //
|
||||
#define bmLOWSPEED 0x02 //
|
||||
#define bmHUBPRE 0x04 //
|
||||
@@ -186,10 +186,10 @@ e-mail : support@circuitsathome.com
|
||||
#define bmDMPULLDN 0x40 //
|
||||
#define bmDPPULLDN 0x80 //
|
||||
|
||||
#define rPERADDR 0xe0 //28<<3
|
||||
#define rPERADDR 0xE0 //28<<3
|
||||
|
||||
// (HCTL)
|
||||
#define rHCTL 0xe8 //29<<3
|
||||
#define rHCTL 0xE8 //29<<3
|
||||
#define bmBUSRST 0x01 //
|
||||
#define bmFRMRST 0x02 //
|
||||
#define bmSAMPLEBUS 0x04 //
|
||||
@@ -200,7 +200,7 @@ e-mail : support@circuitsathome.com
|
||||
#define bmSNDTOG1 0x80 //
|
||||
|
||||
// Host transfer (HXFR)
|
||||
#define rHXFR 0xf0 //30<<3
|
||||
#define rHXFR 0xF0 //30<<3
|
||||
/* Host transfer token values for writing the HXFR register (R30) */
|
||||
/* OR this bit field with the endpoint number in bits 3:0 */
|
||||
#define MAX3421E_tokSETUP 0x10 // HS=0, ISO=0, OUTNIN=0, SETUP=1
|
||||
@@ -212,13 +212,13 @@ e-mail : support@circuitsathome.com
|
||||
#define MAX3421E_tokISOOUT 0x60 // HS=0, ISO=1, OUTNIN=1, SETUP=0
|
||||
|
||||
// (HRSL)
|
||||
#define rHRSL 0xf8 //31<<3
|
||||
#define rHRSL 0xF8 //31<<3
|
||||
#define bmRCVTOGRD 0x10 //
|
||||
#define bmSNDTOGRD 0x20 //
|
||||
#define bmKSTATUS 0x40 //
|
||||
#define bmJSTATUS 0x80 //
|
||||
#define bmSE0 0x00 //SE0 - disconnect state
|
||||
#define bmSE1 0xc0 //SE1 - illegal state
|
||||
#define bmSE1 0xC0 //SE1 - illegal state
|
||||
|
||||
#define MODE_FS_HOST (bmDPPULLDN|bmDMPULLDN|bmHOST|bmSOFKAENAB)
|
||||
#define MODE_LS_HOST (bmDPPULLDN|bmDMPULLDN|bmHOST|bmLOWSPEED|bmSOFKAENAB)
|
||||
|
12
Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/USB_HOST_SHIELD/USB_HOST_SHIELD.h
Executable file → Normal file
12
Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/USB_HOST_SHIELD/USB_HOST_SHIELD.h
Executable file → Normal file
@@ -13,7 +13,7 @@ Contact information
|
||||
-------------------
|
||||
|
||||
Circuits At Home, LTD
|
||||
Web : http://www.circuitsathome.com
|
||||
Web : https://www.circuitsathome.com
|
||||
e-mail : support@circuitsathome.com
|
||||
*/
|
||||
|
||||
@@ -272,11 +272,11 @@ e-mail : support@circuitsathome.com
|
||||
//
|
||||
#define IRQ_SENSE FALLING
|
||||
#ifdef ARDUINO_ARCH_PIC32
|
||||
//#define bmPULSEWIDTH PUSLEWIDTH10_6
|
||||
//#define bmPULSEWIDTH PULSEWIDTH10_6
|
||||
#define bmPULSEWIDTH 0
|
||||
#define bmIRQ_SENSE 0
|
||||
#else
|
||||
#define bmPULSEWIDTH PUSLEWIDTH1_3
|
||||
#define bmPULSEWIDTH PULSEWIDTH1_3
|
||||
#define bmIRQ_SENSE 0
|
||||
#endif
|
||||
#else
|
||||
@@ -388,7 +388,7 @@ public:
|
||||
return (!condet);
|
||||
};
|
||||
|
||||
virtual UHS_EpInfo *ctrlReqOpen(uint8_t addr, uint64_t Request, uint8_t* dataptr);
|
||||
virtual UHS_EpInfo *ctrlReqOpen(uint8_t addr, uint64_t Request, uint8_t *dataptr);
|
||||
|
||||
virtual void UHS_NI vbusPower(VBUS_t state) {
|
||||
regWr(rPINCTL, (bmFDUPSPI | bmIRQ_SENSE) | (uint8_t)(state));
|
||||
@@ -483,8 +483,8 @@ public:
|
||||
void gpioWr(uint8_t data);
|
||||
uint8_t regRd(uint8_t reg);
|
||||
uint8_t gpioRd();
|
||||
uint8_t* bytesWr(uint8_t reg, uint8_t nbytes, uint8_t* data_p);
|
||||
uint8_t* bytesRd(uint8_t reg, uint8_t nbytes, uint8_t* data_p);
|
||||
uint8_t* bytesWr(uint8_t reg, uint8_t nbytes, uint8_t *data_p);
|
||||
uint8_t* bytesRd(uint8_t reg, uint8_t nbytes, uint8_t *data_p);
|
||||
|
||||
// ARM/NVIC specific, used to emulate reentrant ISR.
|
||||
#ifdef SWI_IRQ_NUM
|
||||
|
24
Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/USB_HOST_SHIELD/USB_HOST_SHIELD_INLINE.h
Executable file → Normal file
24
Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/USB_HOST_SHIELD/USB_HOST_SHIELD_INLINE.h
Executable file → Normal file
@@ -13,7 +13,7 @@ Contact information
|
||||
-------------------
|
||||
|
||||
Circuits At Home, LTD
|
||||
Web : http://www.circuitsathome.com
|
||||
Web : https://www.circuitsathome.com
|
||||
e-mail : support@circuitsathome.com
|
||||
*/
|
||||
|
||||
@@ -76,7 +76,7 @@ void UHS_NI MAX3421E_HOST::regWr(uint8_t reg, uint8_t data) {
|
||||
/* multiple-byte write */
|
||||
|
||||
/* returns a pointer to memory position after last written */
|
||||
uint8_t* UHS_NI MAX3421E_HOST::bytesWr(uint8_t reg, uint8_t nbytes, uint8_t* data_p) {
|
||||
uint8_t* UHS_NI MAX3421E_HOST::bytesWr(uint8_t reg, uint8_t nbytes, uint8_t *data_p) {
|
||||
SPIclass.beginTransaction(MAX3421E_SPI_Settings);
|
||||
MARLIN_UHS_WRITE_SS(LOW);
|
||||
SPIclass.transfer(reg | 0x02);
|
||||
@@ -96,7 +96,7 @@ uint8_t* UHS_NI MAX3421E_HOST::bytesWr(uint8_t reg, uint8_t nbytes, uint8_t* dat
|
||||
/* GPIO write */
|
||||
/*GPIO byte is split between 2 registers, so two writes are needed to write one byte */
|
||||
|
||||
/* GPOUT bits are in the low nibble. 0-3 in IOPINS1, 4-7 in IOPINS2 */
|
||||
/* GPOUT bits are in the low nybble. 0-3 in IOPINS1, 4-7 in IOPINS2 */
|
||||
void UHS_NI MAX3421E_HOST::gpioWr(uint8_t data) {
|
||||
regWr(rIOPINS1, data);
|
||||
data >>= 4;
|
||||
@@ -117,7 +117,7 @@ uint8_t UHS_NI MAX3421E_HOST::regRd(uint8_t reg) {
|
||||
/* multiple-byte register read */
|
||||
|
||||
/* returns a pointer to a memory position after last read */
|
||||
uint8_t* UHS_NI MAX3421E_HOST::bytesRd(uint8_t reg, uint8_t nbytes, uint8_t* data_p) {
|
||||
uint8_t* UHS_NI MAX3421E_HOST::bytesRd(uint8_t reg, uint8_t nbytes, uint8_t *data_p) {
|
||||
SPIclass.beginTransaction(MAX3421E_SPI_Settings);
|
||||
MARLIN_UHS_WRITE_SS(LOW);
|
||||
SPIclass.transfer(reg);
|
||||
@@ -132,11 +132,11 @@ uint8_t* UHS_NI MAX3421E_HOST::bytesRd(uint8_t reg, uint8_t nbytes, uint8_t* dat
|
||||
|
||||
/* GPIO read. See gpioWr for explanation */
|
||||
|
||||
/* GPIN pins are in high nibbles of IOPINS1, IOPINS2 */
|
||||
/* GPIN pins are in high nybbles of IOPINS1, IOPINS2 */
|
||||
uint8_t UHS_NI MAX3421E_HOST::gpioRd() {
|
||||
uint8_t gpin = 0;
|
||||
gpin = regRd(rIOPINS2); //pins 4-7
|
||||
gpin &= 0xf0; //clean lower nibble
|
||||
gpin &= 0xF0; //clean lower nybble
|
||||
gpin |= (regRd(rIOPINS1) >> 4); //shift low bits and OR with upper from previous operation.
|
||||
return ( gpin);
|
||||
}
|
||||
@@ -472,7 +472,7 @@ uint8_t UHS_NI MAX3421E_HOST::SetAddress(uint8_t addr, uint8_t ep, UHS_EpInfo **
|
||||
* @param data pointer to data buffer
|
||||
* @return 0 on success
|
||||
*/
|
||||
uint8_t UHS_NI MAX3421E_HOST::InTransfer(UHS_EpInfo *pep, uint16_t nak_limit, uint16_t *nbytesptr, uint8_t* data) {
|
||||
uint8_t UHS_NI MAX3421E_HOST::InTransfer(UHS_EpInfo *pep, uint16_t nak_limit, uint16_t *nbytesptr, uint8_t *data) {
|
||||
uint8_t rcode = 0;
|
||||
uint8_t pktsize;
|
||||
|
||||
@@ -504,7 +504,7 @@ uint8_t UHS_NI MAX3421E_HOST::InTransfer(UHS_EpInfo *pep, uint16_t nak_limit, ui
|
||||
/* the only case when absence of RCVDAVIRQ makes sense is when toggle error occurred. Need to add handling for that */
|
||||
if((regRd(rHIRQ) & bmRCVDAVIRQ) == 0) {
|
||||
//MAX_HOST_DEBUG(PSTR(">>>>>>>> Problem! NO RCVDAVIRQ!\r\n"));
|
||||
rcode = 0xf0; //receive error
|
||||
rcode = 0xF0; //receive error
|
||||
break;
|
||||
}
|
||||
pktsize = regRd(rRCVBC); //number of received bytes
|
||||
@@ -576,7 +576,7 @@ uint8_t UHS_NI MAX3421E_HOST::OutTransfer(UHS_EpInfo *pep, uint16_t nak_limit, u
|
||||
regWr(rHXFR, (MAX3421E_tokOUT | pep->epAddr)); //dispatch packet
|
||||
while(!(regRd(rHIRQ) & bmHXFRDNIRQ)); //wait for the completion IRQ
|
||||
regWr(rHIRQ, bmHXFRDNIRQ); //clear IRQ
|
||||
rcode = (regRd(rHRSL) & 0x0f);
|
||||
rcode = (regRd(rHRSL) & 0x0F);
|
||||
|
||||
while(rcode && ((long)(millis() - timeout) < 0L)) {
|
||||
switch(rcode) {
|
||||
@@ -606,7 +606,7 @@ uint8_t UHS_NI MAX3421E_HOST::OutTransfer(UHS_EpInfo *pep, uint16_t nak_limit, u
|
||||
regWr(rHXFR, (MAX3421E_tokOUT | pep->epAddr)); //dispatch packet
|
||||
while(!(regRd(rHIRQ) & bmHXFRDNIRQ)); //wait for the completion IRQ
|
||||
regWr(rHIRQ, bmHXFRDNIRQ); //clear IRQ
|
||||
rcode = (regRd(rHRSL) & 0x0f);
|
||||
rcode = (regRd(rHRSL) & 0x0F);
|
||||
SYSTEM_OR_SPECIAL_YIELD();
|
||||
}//while( rcode && ....
|
||||
bytes_left -= bytes_tosend;
|
||||
@@ -631,7 +631,7 @@ breakout:
|
||||
/* If nak_limit == 0, do not count NAKs, exit after timeout */
|
||||
/* If bus timeout, re-sends up to USB_RETRY_LIMIT times */
|
||||
|
||||
/* return codes 0x00-0x0f are HRSLT( 0x00 being success ), 0xff means timeout */
|
||||
/* return codes 0x00-0x0F are HRSLT( 0x00 being success ), 0xFF means timeout */
|
||||
uint8_t UHS_NI MAX3421E_HOST::dispatchPkt(uint8_t token, uint8_t ep, uint16_t nak_limit) {
|
||||
unsigned long timeout = millis() + UHS_HOST_TRANSFER_MAX_MS;
|
||||
uint8_t tmpdata;
|
||||
@@ -654,7 +654,7 @@ uint8_t UHS_NI MAX3421E_HOST::dispatchPkt(uint8_t token, uint8_t ep, uint16_t na
|
||||
|
||||
}//while ( millis() < timeout
|
||||
|
||||
rcode = (regRd(rHRSL) & 0x0f); //analyze transfer result
|
||||
rcode = (regRd(rHRSL) & 0x0F); //analyze transfer result
|
||||
|
||||
switch(rcode) {
|
||||
case UHS_HOST_ERROR_NAK:
|
||||
|
3
Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/macro_logic.h
Executable file → Normal file
3
Marlin/src/sd/usb_flashdrive/lib-uhs3/UHS_host/macro_logic.h
Executable file → Normal file
@@ -6,7 +6,6 @@
|
||||
*
|
||||
* To test:
|
||||
* gcc -DAJK_TEST_MACRO_LOGIC -E macro_logic.h
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef MACRO_LOGIC_H
|
||||
@@ -141,7 +140,7 @@ AJK_IIF(AJK_BITAND(AJK_IS_COMPARABLE(x))(AJK_IS_COMPARABLE(y)) ) \
|
||||
#define AJK_MAKE_FUNS(AJK_v, AJK_args, AJK_count, AJK_body) AJK_EVAL(AJK_REPEAT(AJK_count, AJK_FUN, AJK_v, AJK_args, AJK_body))
|
||||
#ifdef AJK_TEST_MACRO_LOGIC
|
||||
|
||||
#define BODY(AJKindex) some(C, statement); contaning(a, test[AJKindex]);
|
||||
#define BODY(AJKindex) some(C, statement); containing(a, test[AJKindex]);
|
||||
#define ZERO_TIMES_TEST 0
|
||||
#define THREE_TIMES_TEST 3
|
||||
blank > AJK_MAKE_LIST(VARIABLE_, ZERO_TIMES_TEST) < because zero repeats
|
||||
|
2
Marlin/src/sd/usb_flashdrive/lib-uhs3/dyn_SWI/SWI_INLINE.h
Executable file → Normal file
2
Marlin/src/sd/usb_flashdrive/lib-uhs3/dyn_SWI/SWI_INLINE.h
Executable file → Normal file
@@ -165,7 +165,6 @@ static void Init_dyn_SWI() {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param klass class that extends dyn_SWI
|
||||
* @return 0 on queue full, else returns queue position (ones based)
|
||||
*/
|
||||
@@ -219,7 +218,6 @@ static void Init_dyn_SWI() {
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param klass class that extends dyn_SWI
|
||||
* @return 0 on queue full, else returns queue position (ones based)
|
||||
*/
|
||||
|
2
Marlin/src/sd/usb_flashdrive/lib-uhs3/dyn_SWI/dyn_SWI.h
Executable file → Normal file
2
Marlin/src/sd/usb_flashdrive/lib-uhs3/dyn_SWI/dyn_SWI.h
Executable file → Normal file
@@ -75,7 +75,7 @@ extern "C"
|
||||
#define NVIC_NUM_INTERRUPTS ((int)PERIPH_COUNT_IRQn)
|
||||
#endif
|
||||
#define VECTORTABLE_SIZE (NVIC_NUM_INTERRUPTS+16)
|
||||
#define VECTORTABLE_ALIGNMENT (0x100ul)
|
||||
#define VECTORTABLE_ALIGNMENT (0x100UL)
|
||||
#define NVIC_GET_ACTIVE(n) NVIC_GetActive((IRQn_Type)n)
|
||||
#define NVIC_GET_PENDING(n) NVIC_GetPendingIRQ((IRQn_Type)n)
|
||||
#define NVIC_SET_PENDING(n) NVIC_SetPendingIRQ((IRQn_Type)n)
|
||||
|
Reference in New Issue
Block a user