update code base to Marlin 2.0.9.2

This commit is contained in:
Stefan Kalscheuer
2021-10-03 18:57:12 +02:00
parent b9d7ba838e
commit 7077da3591
2617 changed files with 332093 additions and 103438 deletions

112
Marlin/src/sd/Sd2Card.cpp Executable file → Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load Diff

224
Marlin/src/sd/cardreader.h Executable file → Normal file
View 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

View File

@@ -0,0 +1,67 @@
/**
* Marlin 3D Printer Firmware
* Copyright (c) 2021 MarlinFirmware [https://github.com/MarlinFirmware/Marlin]
*
* Based on Sprinter and grbl.
* Copyright (c) 2011 Camiel Gubbels / Erik van der Zalm
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*
*/
#pragma once
#include <stdint.h>
/**
* DiskIO 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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

View 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);

View 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);

View 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) {
}

View 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

View File

View 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.

View 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
*/

View 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__)

View 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 */

View 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);

View 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)

View 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__)

View 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
*/

View 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>

View 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

View 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 */
/*

View 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

View 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
*/

View 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)

View 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

View 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:

View 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

View 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)
*/

View 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)