Format SD card

This commit is contained in:
Spacehuhn 2022-11-02 12:02:15 +01:00
parent 776c09962f
commit b2e0fde025
7 changed files with 204 additions and 10 deletions

View File

@ -11,6 +11,7 @@
#include "src/duckparser/duckparser.h"
#include "src/tasks/tasks.h"
#include "src/cli/cli.h"
#include "src/msc/format.h"
void update() {
led::update();
@ -64,12 +65,12 @@ void setup() {
// Attack settings
keyboard::setLocale(locale::get(preferences::getDefaultLayout().c_str()));
duckparser::setDefaultDelay(preferences::getDefaultDelay());
/*
// Format Flash (if specified in preferences.json)
if ((selector::mode() == SETUP) && preferences::getFormat()) {
led::setColor(255, 255, 255);
msc::format(preferences::getDriveName().c_str());
}*/
}
// Create preferences file if it doesn't exist yet
if (!msc::exists(PREFERENCES_PATH)) {

View File

@ -11,6 +11,7 @@
#include "../attack/attack.h"
#include "../msc/msc.h"
#include "../../config.h"
#include "../msc/format.h"
#define BUFFER_SIZE 1024
@ -92,7 +93,7 @@ namespace cli {
Serial.println("Made with <3 by Spacehuhn (spacehuhn.com)");
Serial.println();
}).setDescription(" Print the firmware version.");
/*
// format
cli.addCmd("format", [](cmd* c) {
led::setColor(255, 255, 255);
@ -107,7 +108,7 @@ namespace cli {
Serial.println("Done formatting!");
Serial.println();
}).setDescription(" Fromat the internal memory.");
*/
// reset
cli.addCmd("reset", [](cmd* c) {
preferences::reset();

184
src/msc/format.cpp Normal file
View File

@ -0,0 +1,184 @@
/* This software is licensed under the MIT License: https://github.com/spacehuhntech/usbnova */
#include "format.h"
#include "../../config.h"
#include "../../debug.h"
/*
* This program will format SD/SDHC/SDXC cards.
* Warning all data will be deleted!
*
* This program attempts to match the format
* generated by SDFormatter available here:
*
* http://www.sdcard.org/consumers/formatter/
*
* For very small cards this program uses FAT16
* and the above SDFormatter uses FAT12.
*/
#include <SdFat.h>
#include <sdios.h>
// Try max SPI clock for an SD. Reduce SPI_CLOCK if errors occur.
#define SPI_CLOCK SD_SCK_MHZ(12)
// Try to select the best SD card configuration.
#if HAS_SDIO_CLASS
#define SD_CONFIG SdioConfig(FIFO_SDIO)
#elif ENABLE_DEDICATED_SPI
#define SD_CONFIG SdSpiConfig(SD_CS, DEDICATED_SPI, SPI_CLOCK)
#else // HAS_SDIO_CLASS
#define SD_CONFIG SdSpiConfig(SD_CS, SHARED_SPI, SPI_CLOCK)
#endif // HAS_SDIO_CLASS
namespace format {
// ========== PRIVATE ========= //
/*
Set DISABLE_CS_PIN to disable a second SPI device.
For example, with the Ethernet shield, set DISABLE_CS_PIN
to 10 to disable the Ethernet controller.
*/
const int8_t DISABLE_CS_PIN = -1;
// Serial output stream
ArduinoOutStream cout(Serial);
uint32_t cardSectorCount = 0;
uint8_t sectorBuffer[512];
SdCardFactory cardFactory; // SdCardFactory constructs and initializes the appropriate card.
SdCard* m_card = nullptr; // Pointer to generic SD card.
#define sdError(msg) {cout << F("error: ") << F(msg) << endl; sdErrorHalt();}
void sdErrorHalt() {
if (!m_card) {
cout << F("Invalid SD_CONFIG") << endl;
} else if (m_card->errorCode()) {
if (m_card->errorCode() == SD_CARD_ERROR_CMD0) {
cout << F("No card, wrong chip select pin, or wiring error?") << endl;
}
cout << F("SD errorCode: ") << hex << showbase;
printSdErrorSymbol(&Serial, m_card->errorCode());
cout << F(" = ") << int(m_card->errorCode()) << endl;
cout << F("SD errorData = ") << int(m_card->errorData()) << endl;
}
while (true) {}
}
void clearSerialInput() {
uint32_t m = micros();
do {
if (Serial.read() >= 0) {
m = micros();
}
} while (micros() - m < 10000);
}
// flash erase all data
uint32_t const ERASE_SIZE = 262144L;
void eraseCard() {
cout << endl << F("Erasing\n");
uint32_t firstBlock = 0;
uint32_t lastBlock;
uint16_t n = 0;
do {
lastBlock = firstBlock + ERASE_SIZE - 1;
if (lastBlock >= cardSectorCount) {
lastBlock = cardSectorCount - 1;
}
if (!m_card->erase(firstBlock, lastBlock)) {
sdError("erase failed");
}
cout << '.';
if ((n++)%64 == 63) {
cout << endl;
}
firstBlock += ERASE_SIZE;
} while (firstBlock < cardSectorCount);
cout << endl;
if (!m_card->readSector(0, sectorBuffer)) {
sdError("readBlock");
}
cout << hex << showbase << setfill('0') << internal;
cout << F("All data set to ") << setw(4) << int(sectorBuffer[0]) << endl;
cout << dec << noshowbase << setfill(' ') << right;
cout << F("Erase done\n");
}
void formatCard() {
ExFatFormatter exFatFormatter;
FatFormatter fatFormatter;
// Format exFAT if larger than 32GB.
bool rtn = cardSectorCount > 67108864 ?
exFatFormatter.format(m_card, sectorBuffer, &Serial) :
fatFormatter.format(m_card, sectorBuffer, &Serial);
if (!rtn) {
sdErrorHalt();
}
cout << F("Run the SdInfo example for format details.") << endl;
}
void printConfig(SdSpiConfig config) {
if (DISABLE_CS_PIN < 0) {
cout << F(
"\nAssuming the SD is the only SPI device.\n"
"Edit DISABLE_CS_PIN to disable an SPI device.\n");
} else {
cout << F("\nDisabling SPI device on pin ");
cout << int(DISABLE_CS_PIN) << endl;
pinMode(DISABLE_CS_PIN, OUTPUT);
digitalWrite(DISABLE_CS_PIN, HIGH);
}
cout << F("\nAssuming the SD chip select pin is: ") << int(config.csPin);
cout << F("\nEdit SD_CS to change the SD chip select pin.\n");
}
void printConfig(SdioConfig config) {
(void)config;
cout << F("Assuming an SDIO interface.\n");
}
// ========== PUBLIC ========= //
bool start(const char* drive_name) {
debugln("Starting format...");
printConfig(SD_CONFIG);
// Select and initialize proper card driver.
m_card = cardFactory.newCard(SD_CONFIG);
if (!m_card || m_card->errorCode()) {
sdError("card init failed.");
return false;
}
cardSectorCount = m_card->sectorCount();
if (!cardSectorCount) {
sdError("Get sector count failed.");
return false;
}
cout << F("\nCard size: ") << cardSectorCount*5.12e-7;
cout << F(" GB (GB = 1E9 bytes)\n");
cout << F("Card size: ") << cardSectorCount/2097152.0;
cout << F(" GiB (GiB = 2^30 bytes)\n");
cout << F("Card will be formated ");
if (cardSectorCount > 67108864) {
cout << F("exFAT\n");
} else if (cardSectorCount > 4194304) {
cout << F("FAT32\n");
} else {
cout << F("FAT16\n");
}
formatCard();
return true;
}
}

7
src/msc/format.h Normal file
View File

@ -0,0 +1,7 @@
/* This software is licensed under the MIT License: https://github.com/spacehuhntech/usbnova */
#pragma once
namespace format {
bool start(const char* drive_name = "MalDuino");
}

View File

@ -4,6 +4,7 @@
#include "../../config.h"
#include "../../debug.h"
#include "format.h"
#include <stack>
@ -84,7 +85,7 @@ namespace msc {
}
bool format(const char* drive_name) {
return false;//format::start(drive_name);
return format::start(drive_name);
}
void print() {

View File

@ -8,7 +8,7 @@
namespace msc {
bool init();
bool format(const char* drive_name = "USB Nova");
bool format(const char* drive_name = "MalDuino");
void print();
void setID(const char* vid, const char* pid, const char* rev);

View File

@ -168,13 +168,13 @@ namespace preferences {
read_array(config_doc, "attack_color", attack_color, 4);
read_array(config_doc, "setup_color", setup_color, 4);
read_array(config_doc, "idle_color", idle_color, 4);
*/
// Format Flash (Drive name/Disk label max 11 characters)
format = config_doc.containsKey("format");
if (format) {
drive_name = config_doc["format"].as<std::string>().substr(0, 11);
}
*/
disable_capslock = config_doc["disable_capslock"].as<bool>();
run_on_indicator = config_doc["run_on_indicator"].as<bool>();
run_on_msc = config_doc["run_on_msc"].as<bool>();
@ -235,10 +235,10 @@ namespace preferences {
idle_color[1] = 0;
idle_color[2] = 0;
idle_color[3] = 0;
*/
format = false;
drive_name = "MalDuino";
*/
disable_capslock = true;
run_on_indicator = false;
run_on_msc = false;